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