001
014
015 package com.liferay.portlet.dynamicdatamapping.util;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
020 import com.liferay.portal.kernel.json.JSONArray;
021 import com.liferay.portal.kernel.json.JSONFactoryUtil;
022 import com.liferay.portal.kernel.json.JSONObject;
023 import com.liferay.portal.kernel.language.LanguageUtil;
024 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
025 import com.liferay.portal.kernel.servlet.JSPSupportServlet;
026 import com.liferay.portal.kernel.template.Template;
027 import com.liferay.portal.kernel.template.TemplateConstants;
028 import com.liferay.portal.kernel.template.TemplateManagerUtil;
029 import com.liferay.portal.kernel.template.TemplateResource;
030 import com.liferay.portal.kernel.template.URLTemplateResource;
031 import com.liferay.portal.kernel.util.ArrayUtil;
032 import com.liferay.portal.kernel.util.CharPool;
033 import com.liferay.portal.kernel.util.GetterUtil;
034 import com.liferay.portal.kernel.util.HtmlUtil;
035 import com.liferay.portal.kernel.util.LocaleUtil;
036 import com.liferay.portal.kernel.util.LocalizationUtil;
037 import com.liferay.portal.kernel.util.ParamUtil;
038 import com.liferay.portal.kernel.util.StringBundler;
039 import com.liferay.portal.kernel.util.StringPool;
040 import com.liferay.portal.kernel.util.StringUtil;
041 import com.liferay.portal.kernel.util.Validator;
042 import com.liferay.portal.kernel.xml.Attribute;
043 import com.liferay.portal.kernel.xml.Document;
044 import com.liferay.portal.kernel.xml.DocumentException;
045 import com.liferay.portal.kernel.xml.Element;
046 import com.liferay.portal.kernel.xml.Node;
047 import com.liferay.portal.kernel.xml.SAXReaderUtil;
048 import com.liferay.portal.kernel.xml.XPath;
049 import com.liferay.portal.util.PortalUtil;
050 import com.liferay.portlet.dynamicdatamapping.io.DDMFormJSONDeserializerUtil;
051 import com.liferay.portlet.dynamicdatamapping.io.DDMFormXSDSerializerUtil;
052 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
053 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
054 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
055 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
056 import com.liferay.portlet.dynamicdatamapping.service.DDMStorageLinkLocalServiceUtil;
057 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
058 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
059 import com.liferay.portlet.dynamicdatamapping.storage.Field;
060 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
061 import com.liferay.util.freemarker.FreeMarkerTaglibFactoryUtil;
062
063 import freemarker.ext.servlet.HttpRequestHashModel;
064 import freemarker.ext.servlet.ServletContextHashModel;
065
066 import freemarker.template.ObjectWrapper;
067 import freemarker.template.TemplateHashModel;
068
069 import java.io.Writer;
070
071 import java.net.URL;
072
073 import java.util.ArrayList;
074 import java.util.HashMap;
075 import java.util.List;
076 import java.util.Locale;
077 import java.util.Map;
078
079 import javax.servlet.GenericServlet;
080 import javax.servlet.http.HttpServletRequest;
081 import javax.servlet.http.HttpServletResponse;
082
083
089 @DoPrivileged
090 public class DDMXSDImpl implements DDMXSD {
091
092 public DDMXSDImpl() {
093 String defaultTemplateId = _TPL_PATH + "alloy/text.ftl";
094
095 URL defaultTemplateURL = getResource(defaultTemplateId);
096
097 _defaultTemplateResource = new URLTemplateResource(
098 defaultTemplateId, defaultTemplateURL);
099
100 String defaultReadOnlyTemplateId = _TPL_PATH + "readonly/default.ftl";
101
102 URL defaultReadOnlyTemplateURL = getResource(defaultReadOnlyTemplateId);
103
104 _defaultReadOnlyTemplateResource = new URLTemplateResource(
105 defaultReadOnlyTemplateId, defaultReadOnlyTemplateURL);
106 }
107
108 @Override
109 public String getFieldHTML(
110 HttpServletRequest request, HttpServletResponse response,
111 Element element, Fields fields, String portletNamespace,
112 String namespace, String mode, boolean readOnly, Locale locale)
113 throws Exception {
114
115 Map<String, Object> freeMarkerContext = getFreeMarkerContext(
116 request, response, portletNamespace, namespace, element, locale);
117
118 if (fields != null) {
119 freeMarkerContext.put("fields", fields);
120 }
121
122 Map<String, Object> fieldStructure =
123 (Map<String, Object>)freeMarkerContext.get("fieldStructure");
124
125 int fieldRepetition = 1;
126 int offset = 0;
127
128 DDMFieldsCounter ddmFieldsCounter = getFieldsCounter(
129 request, response, fields, portletNamespace, namespace);
130
131 String name = element.attributeValue("name");
132
133 String fieldDisplayValue = getFieldsDisplayValue(
134 request, response, fields);
135
136 String[] fieldsDisplayValues = getFieldsDisplayValues(
137 fieldDisplayValue);
138
139 boolean fieldDisplayable = ArrayUtil.contains(
140 fieldsDisplayValues, name);
141
142 if (fieldDisplayable) {
143 Map<String, Object> parentFieldStructure =
144 (Map<String, Object>)freeMarkerContext.get(
145 "parentFieldStructure");
146
147 String parentFieldName = (String)parentFieldStructure.get("name");
148
149 offset = getFieldOffset(
150 fieldsDisplayValues, name, ddmFieldsCounter.get(name));
151
152 if (offset == fieldsDisplayValues.length) {
153 return StringPool.BLANK;
154 }
155
156 fieldRepetition = countFieldRepetition(
157 fieldsDisplayValues, parentFieldName, offset);
158 }
159
160 StringBundler sb = new StringBundler(fieldRepetition);
161
162 while (fieldRepetition > 0) {
163 offset = getFieldOffset(
164 fieldsDisplayValues, name, ddmFieldsCounter.get(name));
165
166 String fieldNamespace = StringUtil.randomId();
167
168 if (fieldDisplayable) {
169 fieldNamespace = getFieldNamespace(
170 fieldDisplayValue, ddmFieldsCounter, offset);
171 }
172
173 fieldStructure.put("fieldNamespace", fieldNamespace);
174
175 fieldStructure.put("valueIndex", ddmFieldsCounter.get(name));
176
177 if (fieldDisplayable) {
178 ddmFieldsCounter.incrementKey(name);
179 }
180
181 String childrenHTML = getHTML(
182 request, response, element, fields, portletNamespace, namespace,
183 mode, readOnly, locale);
184
185 fieldStructure.put("children", childrenHTML);
186
187 boolean disabled = GetterUtil.getBoolean(
188 fieldStructure.get("disabled"), false);
189
190 if (disabled) {
191 readOnly = true;
192 }
193
194 sb.append(
195 processFTL(
196 request, response, element, mode, readOnly,
197 freeMarkerContext));
198
199 fieldRepetition--;
200 }
201
202 return sb.toString();
203 }
204
205 @Override
206 public String getFieldHTMLByName(
207 HttpServletRequest request, HttpServletResponse response,
208 long classNameId, long classPK, String fieldName, Fields fields,
209 String portletNamespace, String namespace, String mode,
210 boolean readOnly, Locale locale)
211 throws Exception {
212
213 String xsd = getXSD(classNameId, classPK);
214
215 Document document = SAXReaderUtil.read(xsd);
216
217 String xPathExpression = "
218 HtmlUtil.escapeXPathAttribute(fieldName)).concat("]");
219
220 XPath xPathSelector = SAXReaderUtil.createXPath(xPathExpression);
221
222 Node node = xPathSelector.selectSingleNode(document.getRootElement());
223
224 Element element = (Element)node.asXPathResult(node.getParent());
225
226 return getFieldHTML(
227 request, response, element, fields, portletNamespace, namespace,
228 mode, readOnly, locale);
229 }
230
231 @Override
232 public String getHTML(
233 HttpServletRequest request, HttpServletResponse response,
234 DDMStructure ddmStructure, Fields fields, String portletNamespace,
235 String namespace, boolean readOnly, Locale locale)
236 throws Exception {
237
238 return getHTML(
239 request, response, ddmStructure.getDefinition(), fields,
240 portletNamespace, namespace, readOnly, locale);
241 }
242
243 @Override
244 public String getHTML(
245 HttpServletRequest request, HttpServletResponse response,
246 DDMTemplate ddmTemplate, Fields fields, String portletNamespace,
247 String namespace, boolean readOnly, Locale locale)
248 throws Exception {
249
250 return getHTML(
251 request, response, ddmTemplate.getScript(), fields,
252 portletNamespace, namespace, ddmTemplate.getMode(), readOnly,
253 locale);
254 }
255
256 public String getHTML(
257 HttpServletRequest request, HttpServletResponse response,
258 Element element, Fields fields, String portletNamespace,
259 Locale locale)
260 throws Exception {
261
262 return getHTML(
263 request, response, element, fields, portletNamespace,
264 StringPool.BLANK, null, false, locale);
265 }
266
267 public String getHTML(
268 HttpServletRequest request, HttpServletResponse response,
269 Element element, Fields fields, String portletNamespace,
270 String namespace, String mode, boolean readOnly, Locale locale)
271 throws Exception {
272
273 List<Element> dynamicElementElements = element.elements(
274 "dynamic-element");
275
276 StringBundler sb = new StringBundler(dynamicElementElements.size());
277
278 for (Element dynamicElementElement : dynamicElementElements) {
279 sb.append(
280 getFieldHTML(
281 request, response, dynamicElementElement, fields,
282 portletNamespace, namespace, mode, readOnly, locale));
283 }
284
285 return sb.toString();
286 }
287
288 public String getHTML(
289 HttpServletRequest request, HttpServletResponse response,
290 Element element, String portletNamespace, Locale locale)
291 throws Exception {
292
293 return getHTML(
294 request, response, element, null, portletNamespace, locale);
295 }
296
297 @Override
298 public String getHTML(
299 HttpServletRequest request, HttpServletResponse response,
300 String xml, Fields fields, String portletNamespace, Locale locale)
301 throws Exception {
302
303 return getHTML(
304 request, response, xml, fields, portletNamespace, StringPool.BLANK,
305 locale);
306 }
307
308 @Override
309 public String getHTML(
310 HttpServletRequest request, HttpServletResponse response,
311 String xml, Fields fields, String portletNamespace,
312 String namespace, boolean readOnly, Locale locale)
313 throws Exception {
314
315 return getHTML(
316 request, response, xml, fields, portletNamespace, namespace, null,
317 readOnly, locale);
318 }
319
320 @Override
321 public String getHTML(
322 HttpServletRequest request, HttpServletResponse response,
323 String xml, Fields fields, String portletNamespace,
324 String namespace, Locale locale)
325 throws Exception {
326
327 return getHTML(
328 request, response, xml, fields, portletNamespace, namespace, false,
329 locale);
330 }
331
332 @Override
333 public String getHTML(
334 HttpServletRequest request, HttpServletResponse response,
335 String xml, Fields fields, String portletNamespace,
336 String namespace, String mode, boolean readOnly, Locale locale)
337 throws Exception {
338
339 Document document = SAXReaderUtil.read(xml);
340
341 return getHTML(
342 request, response, document.getRootElement(), fields,
343 portletNamespace, namespace, mode, readOnly, locale);
344 }
345
346 @Override
347 public String getHTML(
348 HttpServletRequest request, HttpServletResponse response,
349 String xml, String portletNamespace, Locale locale)
350 throws Exception {
351
352 return getHTML(request, response, xml, null, locale);
353 }
354
355 @Override
356 public JSONArray getJSONArray(DDMStructure structure, String xsd)
357 throws PortalException {
358
359 JSONArray jsonArray = null;
360
361 if (Validator.isNull(xsd)) {
362 jsonArray = getJSONArray(structure.getDefinition());
363 }
364 else {
365 jsonArray = getJSONArray(xsd);
366 }
367
368 addStructureFieldAttributes(structure, jsonArray);
369
370 return jsonArray;
371 }
372
373 @Override
374 public JSONArray getJSONArray(Document document) throws PortalException {
375 return getJSONArray(document.getRootElement());
376 }
377
378 @Override
379 public JSONArray getJSONArray(Element element) throws PortalException {
380 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
381
382 Document document = element.getDocument();
383
384 String defaultLanguageId = LocalizationUtil.getDefaultLanguageId(
385 document.asXML());
386
387 List<Element> dynamicElementElements = element.elements(
388 "dynamic-element");
389
390 for (Element dynamicElementElement : dynamicElementElements) {
391 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
392 JSONObject localizationMapJSONObject =
393 JSONFactoryUtil.createJSONObject();
394
395 for (Attribute attribute : dynamicElementElement.attributes()) {
396 jsonObject.put(attribute.getName(), attribute.getValue());
397 }
398
399 jsonObject.put("autoGeneratedName", false);
400 jsonObject.put("id", dynamicElementElement.attributeValue("name"));
401
402 String type = jsonObject.getString("type");
403
404 List<Element> metadataElements = dynamicElementElement.elements(
405 "meta-data");
406
407 for (Element metadataElement : metadataElements) {
408 if (metadataElement == null) {
409 continue;
410 }
411
412 String locale = metadataElement.attributeValue("locale");
413
414 JSONObject localeMap = JSONFactoryUtil.createJSONObject();
415
416 for (Element metadataEntryElement :
417 metadataElement.elements()) {
418
419 String attributeName = metadataEntryElement.attributeValue(
420 "name");
421 String attributeValue = metadataEntryElement.getTextTrim();
422
423 putMetadataValue(
424 localeMap, attributeName, attributeValue, type);
425
426 if (defaultLanguageId.equals(locale)) {
427 putMetadataValue(
428 jsonObject, attributeName, attributeValue, type);
429 }
430 }
431
432 localizationMapJSONObject.put(locale, localeMap);
433 }
434
435 jsonObject.put("localizationMap", localizationMapJSONObject);
436
437 JSONArray hiddenAttributesJSONArray =
438 JSONFactoryUtil.createJSONArray();
439
440 if (type.equals(DDMImpl.TYPE_CHECKBOX)) {
441 hiddenAttributesJSONArray.put("required");
442 }
443
444 hiddenAttributesJSONArray.put("readOnly");
445
446 jsonObject.put("hiddenAttributes", hiddenAttributesJSONArray);
447
448 String key = "fields";
449
450 if (type.equals(DDMImpl.TYPE_RADIO) ||
451 type.equals(DDMImpl.TYPE_SELECT)) {
452
453 key = "options";
454 }
455
456 jsonObject.put(key, getJSONArray(dynamicElementElement));
457
458 jsonArray.put(jsonObject);
459 }
460
461 return jsonArray;
462 }
463
464 @Override
465 public JSONArray getJSONArray(String xml) throws PortalException {
466 try {
467 return getJSONArray(SAXReaderUtil.read(xml));
468 }
469 catch (DocumentException de) {
470 throw new SystemException();
471 }
472 }
473
474 @Override
475 public String getSimpleFieldHTML(
476 HttpServletRequest request, HttpServletResponse response,
477 Element element, Field field, String portletNamespace,
478 String namespace, String mode, boolean readOnly, Locale locale)
479 throws Exception {
480
481 Map<String, Object> freeMarkerContext = getFreeMarkerContext(
482 request, response, portletNamespace, namespace, element, locale);
483
484 freeMarkerContext.put("ignoreRepeatable", Boolean.TRUE);
485
486 Map<String, Object> fieldStructure =
487 (Map<String, Object>)freeMarkerContext.get("fieldStructure");
488
489 DDMFieldsCounter ddmFieldsCounter = getFieldsCounter(
490 request, response, null, portletNamespace, namespace);
491
492 String name = element.attributeValue("name");
493
494 if ((field != null) && Validator.isNotNull(field.getValue())) {
495 Fields fields = new Fields();
496
497 fields.put(field);
498
499 freeMarkerContext.put("fields", fields);
500 }
501
502 fieldStructure.put("fieldNamespace", StringUtil.randomId());
503 fieldStructure.put("valueIndex", ddmFieldsCounter.get(name));
504
505 List<Element> dynamicElementElements = element.elements(
506 "dynamic-element");
507
508 StringBundler sb = new StringBundler(dynamicElementElements.size());
509
510 for (Element dynamicElementElement : dynamicElementElements) {
511 String type = dynamicElementElement.attributeValue("type");
512
513 if (!type.equals("option")) {
514 sb.append(StringPool.BLANK);
515 }
516 else {
517 sb.append(
518 getSimpleFieldHTML(
519 request, response, dynamicElementElement, field,
520 portletNamespace, namespace, mode, readOnly, locale));
521 }
522 }
523
524 fieldStructure.put("children", sb.toString());
525
526 return processFTL(
527 request, response, element, mode, readOnly, freeMarkerContext);
528 }
529
530 @Override
531 public String getSimpleFieldHTMLByName(
532 HttpServletRequest request, HttpServletResponse response,
533 long classNameId, long classPK, Field field,
534 String portletNamespace, String namespace, String mode,
535 boolean readOnly, Locale locale)
536 throws Exception {
537
538 String xsd = getXSD(classNameId, classPK);
539
540 Document document = SAXReaderUtil.read(xsd);
541
542 String xPathExpression = "
543 HtmlUtil.escapeXPathAttribute(field.getName())).concat("]");
544
545 XPath xPathSelector = SAXReaderUtil.createXPath(xPathExpression);
546
547 Node node = xPathSelector.selectSingleNode(document.getRootElement());
548
549 Element element = (Element)node.asXPathResult(node.getParent());
550
551 return getSimpleFieldHTML(
552 request, response, element, field, portletNamespace, namespace,
553 mode, readOnly, locale);
554 }
555
556 @Override
557 public String getXSD(long classNameId, long classPK)
558 throws PortalException {
559
560 if ((classNameId <= 0) || (classPK <= 0)) {
561 return null;
562 }
563
564 long ddmStructureClassNameId = PortalUtil.getClassNameId(
565 DDMStructure.class);
566
567 long ddmTemplateClassNameId = PortalUtil.getClassNameId(
568 DDMTemplate.class);
569
570 if (classNameId == ddmStructureClassNameId) {
571 DDMStructure structure = DDMStructureLocalServiceUtil.getStructure(
572 classPK);
573
574 DDMForm ddmForm = structure.getFullHierarchyDDMForm();
575
576 return DDMFormXSDSerializerUtil.serialize(ddmForm);
577 }
578 else if (classNameId == ddmTemplateClassNameId) {
579 DDMTemplate template = DDMTemplateLocalServiceUtil.getTemplate(
580 classPK);
581
582 return template.getScript();
583 }
584
585 return null;
586 }
587
588 @Override
589 public String getXSD(String json) throws PortalException {
590 DDMForm ddmForm = DDMFormJSONDeserializerUtil.deserialize(json);
591
592 return DDMFormXSDSerializerUtil.serialize(ddmForm);
593 }
594
595 protected JSONArray addStructureFieldAttributes(
596 DDMStructure structure, JSONArray jsonArray) {
597
598 for (int i = 0; i < jsonArray.length(); i++) {
599 JSONObject jsonObject = jsonArray.getJSONObject(i);
600
601 String fieldName = jsonObject.getString("name");
602
603 jsonObject.put(
604 "readOnlyAttributes",
605 getStructureFieldReadOnlyAttributes(structure, fieldName));
606 }
607
608 return jsonArray;
609 }
610
611 protected int countFieldRepetition(
612 String[] fieldsDisplayValues, String parentFieldName, int offset) {
613
614 int total = 0;
615
616 String fieldName = fieldsDisplayValues[offset];
617
618 for (; offset < fieldsDisplayValues.length; offset++) {
619 String fieldNameValue = fieldsDisplayValues[offset];
620
621 if (fieldNameValue.equals(fieldName)) {
622 total++;
623 }
624
625 if (fieldNameValue.equals(parentFieldName)) {
626 break;
627 }
628 }
629
630 return total;
631 }
632
633 protected Map<String, Object> getFieldContext(
634 HttpServletRequest request, HttpServletResponse response,
635 String portletNamespace, String namespace,
636 Element dynamicElementElement, Locale locale) {
637
638 Map<String, Map<String, Object>> fieldsContext = getFieldsContext(
639 request, response, portletNamespace, namespace);
640
641 String name = dynamicElementElement.attributeValue("name");
642
643 Map<String, Object> fieldContext = fieldsContext.get(name);
644
645 if (fieldContext != null) {
646 return fieldContext;
647 }
648
649 Document document = dynamicElementElement.getDocument();
650
651 String[] availableLanguageIds =
652 LocalizationUtil.getAvailableLanguageIds(document);
653
654 String defaultLanguageId = LocalizationUtil.getDefaultLanguageId(
655 document);
656
657 String editingLanguageId = LocaleUtil.toLanguageId(locale);
658
659 String structureLanguageId = editingLanguageId;
660
661 if (!ArrayUtil.contains(availableLanguageIds, editingLanguageId)) {
662 structureLanguageId = defaultLanguageId;
663 }
664
665 Element metadataElement =
666 (Element)dynamicElementElement.selectSingleNode(
667 "meta-data[@locale='" + structureLanguageId + "']");
668
669 fieldContext = new HashMap<String, Object>();
670
671 if (metadataElement != null) {
672 for (Element metadataEntry : metadataElement.elements()) {
673 fieldContext.put(
674 metadataEntry.attributeValue("name"),
675 metadataEntry.getText());
676 }
677 }
678
679 for (Attribute attribute : dynamicElementElement.attributes()) {
680 fieldContext.put(attribute.getName(), attribute.getValue());
681 }
682
683 boolean localizable = GetterUtil.getBoolean(
684 dynamicElementElement.attributeValue("localizable"), true);
685
686 if (!localizable && !editingLanguageId.equals(defaultLanguageId)) {
687 fieldContext.put("disabled", Boolean.TRUE.toString());
688 }
689
690 fieldContext.put("fieldNamespace", StringUtil.randomId());
691
692 boolean checkRequired = GetterUtil.getBoolean(
693 request.getAttribute("checkRequired"), true);
694
695 if (!checkRequired) {
696 fieldContext.put("required", Boolean.FALSE.toString());
697 }
698
699 fieldsContext.put(name, fieldContext);
700
701 return fieldContext;
702 }
703
704 protected String getFieldNamespace(
705 String fieldDisplayValue, DDMFieldsCounter ddmFieldsCounter,
706 int offset) {
707
708 String[] fieldsDisplayValues = StringUtil.split(fieldDisplayValue);
709
710 String fieldsDisplayValue = fieldsDisplayValues[offset];
711
712 return StringUtil.extractLast(
713 fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
714 }
715
716 protected int getFieldOffset(
717 String[] fieldsDisplayValues, String name, int index) {
718
719 int offset = 0;
720
721 for (; offset < fieldsDisplayValues.length; offset++) {
722 if (name.equals(fieldsDisplayValues[offset])) {
723 index--;
724
725 if (index < 0) {
726 break;
727 }
728 }
729 }
730
731 return offset;
732 }
733
734 protected Map<String, Map<String, Object>> getFieldsContext(
735 HttpServletRequest request, HttpServletResponse response,
736 String portletNamespace, String namespace) {
737
738 String fieldsContextKey =
739 portletNamespace + namespace + "fieldsContext";
740
741 Map<String, Map<String, Object>> fieldsContext =
742 (Map<String, Map<String, Object>>)request.getAttribute(
743 fieldsContextKey);
744
745 if (fieldsContext == null) {
746 fieldsContext = new HashMap<String, Map<String, Object>>();
747
748 request.setAttribute(fieldsContextKey, fieldsContext);
749 }
750
751 return fieldsContext;
752 }
753
754 protected DDMFieldsCounter getFieldsCounter(
755 HttpServletRequest request, HttpServletResponse response, Fields fields,
756 String portletNamespace, String namespace) {
757
758 String fieldsCounterKey = portletNamespace + namespace + "fieldsCount";
759
760 DDMFieldsCounter ddmFieldsCounter =
761 (DDMFieldsCounter)request.getAttribute(fieldsCounterKey);
762
763 if (ddmFieldsCounter == null) {
764 ddmFieldsCounter = new DDMFieldsCounter();
765
766 request.setAttribute(fieldsCounterKey, ddmFieldsCounter);
767 }
768
769 return ddmFieldsCounter;
770 }
771
772 protected String getFieldsDisplayValue(
773 HttpServletRequest request, HttpServletResponse response,
774 Fields fields) {
775
776 String defaultFieldsDisplayValue = null;
777
778 if (fields != null) {
779 Field fieldsDisplayField = fields.get(DDMImpl.FIELDS_DISPLAY_NAME);
780
781 if (fieldsDisplayField != null) {
782 defaultFieldsDisplayValue =
783 (String)fieldsDisplayField.getValue();
784 }
785 }
786
787 return ParamUtil.getString(
788 request, DDMImpl.FIELDS_DISPLAY_NAME, defaultFieldsDisplayValue);
789 }
790
791 protected String[] getFieldsDisplayValues(String fieldDisplayValue) {
792 List<String> fieldsDisplayValues = new ArrayList<String>();
793
794 for (String value : StringUtil.split(fieldDisplayValue)) {
795 String fieldName = StringUtil.extractFirst(
796 value, DDMImpl.INSTANCE_SEPARATOR);
797
798 fieldsDisplayValues.add(fieldName);
799 }
800
801 return fieldsDisplayValues.toArray(
802 new String[fieldsDisplayValues.size()]);
803 }
804
805 protected Map<String, Object> getFreeMarkerContext(
806 HttpServletRequest request, HttpServletResponse response,
807 String portletNamespace, String namespace,
808 Element dynamicElementElement, Locale locale) {
809
810 Map<String, Object> freeMarkerContext = new HashMap<String, Object>();
811
812 Map<String, Object> fieldContext = getFieldContext(
813 request, response, portletNamespace, namespace,
814 dynamicElementElement, locale);
815
816 Map<String, Object> parentFieldContext = new HashMap<String, Object>();
817
818 Element parentElement = dynamicElementElement.getParent();
819
820 if (parentElement != null) {
821 parentFieldContext = getFieldContext(
822 request, response, portletNamespace, namespace, parentElement,
823 locale);
824 }
825
826 freeMarkerContext.put("fieldStructure", fieldContext);
827 freeMarkerContext.put("namespace", namespace);
828 freeMarkerContext.put("parentFieldStructure", parentFieldContext);
829 freeMarkerContext.put("portletNamespace", portletNamespace);
830 freeMarkerContext.put(
831 "requestedLanguageDir", LanguageUtil.get(locale, "lang.dir"));
832 freeMarkerContext.put("requestedLocale", locale);
833
834 return freeMarkerContext;
835 }
836
837 protected URL getResource(String name) {
838 Class<?> clazz = getClass();
839
840 ClassLoader classLoader = clazz.getClassLoader();
841
842 return classLoader.getResource(name);
843 }
844
845 protected JSONArray getStructureFieldReadOnlyAttributes(
846 DDMStructure structure, String fieldName) {
847
848 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
849
850 try {
851 if (DDMStorageLinkLocalServiceUtil.getStructureStorageLinksCount(
852 structure.getStructureId()) > 0) {
853
854 jsonArray.put("name");
855 }
856 }
857 catch (Exception e) {
858 }
859
860 return jsonArray;
861 }
862
863 protected String processFTL(
864 HttpServletRequest request, HttpServletResponse response,
865 Element element, String mode, boolean readOnly,
866 Map<String, Object> freeMarkerContext)
867 throws Exception {
868
869 String fieldNamespace = element.attributeValue(
870 "fieldNamespace", _DEFAULT_NAMESPACE);
871
872 TemplateResource templateResource = _defaultTemplateResource;
873
874 Map<String, Object> fieldStructure =
875 (Map<String, Object>)freeMarkerContext.get("fieldStructure");
876
877 boolean fieldReadOnly = GetterUtil.getBoolean(
878 fieldStructure.get("readOnly"));
879
880 if ((fieldReadOnly && Validator.isNotNull(mode) &&
881 StringUtil.equalsIgnoreCase(
882 mode, DDMTemplateConstants.TEMPLATE_MODE_EDIT)) ||
883 readOnly) {
884
885 fieldNamespace = _DEFAULT_READ_ONLY_NAMESPACE;
886
887 templateResource = _defaultReadOnlyTemplateResource;
888 }
889
890 String type = element.attributeValue("type");
891
892 String templateName = StringUtil.replaceFirst(
893 type, fieldNamespace.concat(StringPool.DASH), StringPool.BLANK);
894
895 StringBundler resourcePath = new StringBundler(5);
896
897 resourcePath.append(_TPL_PATH);
898 resourcePath.append(StringUtil.toLowerCase(fieldNamespace));
899 resourcePath.append(CharPool.SLASH);
900 resourcePath.append(templateName);
901 resourcePath.append(_TPL_EXT);
902
903 String resource = resourcePath.toString();
904
905 URL url = getResource(resource);
906
907 if (url != null) {
908 templateResource = new URLTemplateResource(resource, url);
909 }
910
911 if (templateResource == null) {
912 throw new Exception("Unable to load template resource " + resource);
913 }
914
915 Template template = TemplateManagerUtil.getTemplate(
916 TemplateConstants.LANG_TYPE_FTL, templateResource, false);
917
918 for (Map.Entry<String, Object> entry : freeMarkerContext.entrySet()) {
919 template.put(entry.getKey(), entry.getValue());
920 }
921
922 return processFTL(request, response, template);
923 }
924
925
928 protected String processFTL(
929 HttpServletRequest request, HttpServletResponse response,
930 Template template)
931 throws Exception {
932
933
934
935 template.prepare(request);
936
937
938
939 Writer writer = new UnsyncStringWriter();
940
941
942
943 TemplateHashModel portalTaglib =
944 FreeMarkerTaglibFactoryUtil.createTaglibFactory(
945 request.getServletContext());
946
947 template.put("PortalJspTagLibs", portalTaglib);
948
949
950
951 GenericServlet genericServlet = new JSPSupportServlet(
952 request.getServletContext());
953
954 ServletContextHashModel servletContextHashModel =
955 new ServletContextHashModel(
956 genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
957
958 template.put("Application", servletContextHashModel);
959
960 HttpRequestHashModel httpRequestHashModel = new HttpRequestHashModel(
961 request, response, ObjectWrapper.DEFAULT_WRAPPER);
962
963 template.put("Request", httpRequestHashModel);
964
965
966
967 template.processTemplate(writer);
968
969 return writer.toString();
970 }
971
972 protected void putMetadataValue(
973 JSONObject jsonObject, String attributeName, String attributeValue,
974 String type) {
975
976 if (type.equals(DDMImpl.TYPE_RADIO) ||
977 type.equals(DDMImpl.TYPE_SELECT)) {
978
979 if (attributeName.equals("predefinedValue")) {
980 try {
981 jsonObject.put(
982 attributeName,
983 JSONFactoryUtil.createJSONArray(attributeValue));
984 }
985 catch (Exception e) {
986 }
987
988 return;
989 }
990 }
991
992 jsonObject.put(attributeName, attributeValue);
993 }
994
995 private static final String _DEFAULT_NAMESPACE = "alloy";
996
997 private static final String _DEFAULT_READ_ONLY_NAMESPACE = "readonly";
998
999 private static final String _TPL_EXT = ".ftl";
1000
1001 private static final String _TPL_PATH =
1002 "com/liferay/portlet/dynamicdatamapping/dependencies/";
1003
1004 private TemplateResource _defaultReadOnlyTemplateResource;
1005 private TemplateResource _defaultTemplateResource;
1006
1007 }