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