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