001
014
015 package com.liferay.portlet.journal.util;
016
017 import com.liferay.portal.kernel.json.JSONArray;
018 import com.liferay.portal.kernel.json.JSONFactoryUtil;
019 import com.liferay.portal.kernel.json.JSONObject;
020 import com.liferay.portal.kernel.repository.model.FileEntry;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.kernel.util.CharPool;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.LocaleUtil;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.xml.Attribute;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.SAXReaderUtil;
031 import com.liferay.portal.kernel.xml.XPath;
032 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
033 import com.liferay.portlet.documentlibrary.util.DLUtil;
034 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
035 import com.liferay.portlet.dynamicdatamapping.storage.Field;
036 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
037 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
038 import com.liferay.portlet.dynamicdatamapping.util.DDMFieldsCounter;
039 import com.liferay.portlet.dynamicdatamapping.util.DDMImpl;
040 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
041 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
042 import com.liferay.util.PwdGenerator;
043
044 import java.io.Serializable;
045
046 import java.util.HashMap;
047 import java.util.List;
048 import java.util.Locale;
049 import java.util.Map;
050 import java.util.Set;
051
052
056 public class JournalConverterUtil {
057
058 public static Fields getDDMFields(DDMStructure ddmStructure, String xml)
059 throws Exception {
060
061 Document document = SAXReaderUtil.read(xml);
062
063 Field fieldsDisplayField = new Field(
064 ddmStructure.getStructureId(), DDMImpl.FIELDS_DISPLAY_NAME,
065 StringPool.BLANK);
066
067 Fields ddmFields = new Fields();
068
069 ddmFields.put(fieldsDisplayField);
070
071 Element rootElement = document.getRootElement();
072
073 String defaultLocale = rootElement.attributeValue("default-locale");
074
075 List<Element> dynamicElementElements = rootElement.elements(
076 "dynamic-element");
077
078 for (Element dynamicElementElement : dynamicElementElements) {
079 addDDMFields(
080 dynamicElementElement, ddmStructure, ddmFields, defaultLocale);
081 }
082
083 return ddmFields;
084 }
085
086 public static String getDDMXSD(String journalXSD) throws Exception {
087 Document document = SAXReaderUtil.read(journalXSD);
088
089 Element rootElement = document.getRootElement();
090
091 Locale defaultLocale = LocaleUtil.getDefault();
092
093 rootElement.addAttribute("available-locales", defaultLocale.toString());
094 rootElement.addAttribute("default-locale", defaultLocale.toString());
095
096 List<Element> dynamicElementElements = rootElement.elements(
097 "dynamic-element");
098
099 for (Element dynamicElementElement : dynamicElementElements) {
100 updateXSDDynamicElement(dynamicElementElement);
101 }
102
103 return DDMXMLUtil.formatXML(document);
104 }
105
106 public static String getXML(DDMStructure ddmStructure, Fields ddmFields)
107 throws Exception {
108
109 Document document = SAXReaderUtil.createDocument();
110
111 Element rootElement = document.addElement("root");
112
113 String availableLocales = getAvailableLocales(ddmFields);
114
115 rootElement.addAttribute("available-locales", availableLocales);
116
117 Locale defaultLocale = ddmFields.getDefaultLocale();
118
119 rootElement.addAttribute(
120 "default-locale", LocaleUtil.toLanguageId(defaultLocale));
121
122 DDMFieldsCounter ddmFieldsCounter = new DDMFieldsCounter();
123
124 for (String fieldName : ddmStructure.getRootFieldNames()) {
125 int repetitions = countFieldRepetition(
126 ddmFields, fieldName, null, -1);
127
128 for (int i = 0; i < repetitions; i++) {
129 Element dynamicElementElement = rootElement.addElement(
130 "dynamic-element");
131
132 dynamicElementElement.addAttribute("name", fieldName);
133
134 updateContentDynamicElement(
135 dynamicElementElement, ddmStructure, ddmFields,
136 ddmFieldsCounter);
137 }
138 }
139
140 return DDMXMLUtil.formatXML(document.asXML());
141 }
142
143 protected static void addDDMFields(
144 Element dynamicElementElement, DDMStructure ddmStructure,
145 Fields ddmFields, String defaultLocale)
146 throws Exception {
147
148 String name = dynamicElementElement.attributeValue("name");
149
150 if (!ddmStructure.hasField(name)) {
151 return;
152 }
153
154 Field ddmField = getField(
155 dynamicElementElement, ddmStructure, defaultLocale);
156
157 String fieldName = ddmField.getName();
158
159 Field existingDDMField = ddmFields.get(fieldName);
160
161 if (existingDDMField != null) {
162 for (Locale locale : ddmField.getAvailableLocales()) {
163 existingDDMField.addValues(locale, ddmField.getValues(locale));
164 }
165 }
166 else {
167 ddmFields.put(ddmField);
168 }
169
170 updateFieldsDisplay(ddmFields, fieldName);
171
172 List<Element> childrenDynamicElementElements =
173 dynamicElementElement.elements("dynamic-element");
174
175 for (Element childrenDynamicElementElement :
176 childrenDynamicElementElements) {
177
178 addDDMFields(
179 childrenDynamicElementElement, ddmStructure, ddmFields,
180 defaultLocale);
181 }
182 }
183
184 protected static void addMetadataAttribute(
185 Element metadataElement, String name, String value) {
186
187 Element entryElement = metadataElement.addElement("entry");
188
189 entryElement.addAttribute("name", name);
190 entryElement.addCDATA(value);
191 }
192
193 protected static int countFieldRepetition(
194 Fields ddmFields, String fieldName, String parentFieldName,
195 int parentOffset)
196 throws Exception {
197
198 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
199
200 String[] fieldsDisplayValues = DDMUtil.getFieldsDisplayValues(
201 fieldsDisplayField);
202
203 int offset = -1;
204
205 int repetitions = 0;
206
207 for (int i = 0; i < fieldsDisplayValues.length; i++) {
208 String fieldDisplayName = fieldsDisplayValues[i];
209
210 if (offset > parentOffset) {
211 break;
212 }
213
214 if (fieldDisplayName.equals(parentFieldName)) {
215 offset++;
216 }
217
218 if (fieldDisplayName.equals(fieldName) &&
219 (offset == parentOffset)) {
220
221 repetitions++;
222 }
223 }
224
225 return repetitions;
226 }
227
228 protected static String getAvailableLocales(Fields ddmFields) {
229 Set<Locale> availableLocales = ddmFields.getAvailableLocales();
230
231 Locale[] availableLocalesArray = new Locale[availableLocales.size()];
232
233 availableLocalesArray = availableLocales.toArray(availableLocalesArray);
234
235 String[] languageIds = LocaleUtil.toLanguageIds(availableLocalesArray);
236
237 return StringUtil.merge(languageIds);
238 }
239
240 protected static Field getField(
241 Element dynamicElementElement, DDMStructure ddmStructure,
242 String defaultLocale)
243 throws Exception {
244
245 Field ddmField = new Field();
246
247 ddmField.setDDMStructureId(ddmStructure.getStructureId());
248 ddmField.setDefaultLocale(LocaleUtil.fromLanguageId(defaultLocale));
249
250 String name = dynamicElementElement.attributeValue("name");
251
252 ddmField.setName(name);
253
254 String dataType = ddmStructure.getFieldDataType(name);
255 String type = ddmStructure.getFieldType(name);
256
257 List<Element> dynamicContentElements = dynamicElementElement.elements(
258 "dynamic-content");
259
260 for (Element dynamicContentElement : dynamicContentElements) {
261 Locale locale = LocaleUtil.fromLanguageId(
262 dynamicContentElement.attributeValue("language-id"));
263
264 Serializable serializable = getFieldValue(
265 dataType, type, dynamicContentElement);
266
267 ddmField.addValue(locale, serializable);
268 }
269
270 return ddmField;
271 }
272
273 protected static Serializable getFieldValue(
274 String dataType, String type, Element dynamicContentElement)
275 throws Exception {
276
277 Serializable serializable = null;
278
279 if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(type)) {
280 String[] pathArray = StringUtil.split(
281 dynamicContentElement.getText(), CharPool.SLASH);
282
283 long groupId = GetterUtil.getLong(pathArray[2]);
284
285 FileEntry fileEntry =
286 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
287 pathArray[5], groupId);
288
289 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
290
291 jsonObject.put("groupId", fileEntry.getGroupId());
292 jsonObject.put("uuid", fileEntry.getUuid());
293 jsonObject.put("version", fileEntry.getVersion());
294
295 serializable = jsonObject.toString();
296 }
297 else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(type)) {
298 String[] values = StringUtil.split(
299 dynamicContentElement.getText(), CharPool.AT);
300
301 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
302
303 jsonObject.put("layoutId", values[0]);
304
305 if (values[1].equals("public")) {
306 jsonObject.put("privateLayout", false);
307 }
308 else {
309 jsonObject.put("privateLayout", true);
310 }
311
312 serializable = jsonObject.toString();
313 }
314 else if (DDMImpl.TYPE_SELECT.equals(type)) {
315 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
316
317 List<Element> optionElements = dynamicContentElement.elements(
318 "option");
319
320 if (optionElements.size() > 0) {
321 for (Element optionElement : optionElements) {
322 jsonArray.put(optionElement.getText());
323 }
324 }
325 else {
326 jsonArray.put(dynamicContentElement.getText());
327 }
328
329 serializable = jsonArray.toString();
330 }
331 else {
332 serializable = FieldConstants.getSerializable(
333 dataType, dynamicContentElement.getText());
334 }
335
336 return serializable;
337 }
338
339 protected static void updateContentDynamicElement(
340 Element dynamicElementElement, DDMStructure ddmStructure,
341 Field ddmField, DDMFieldsCounter ddmFieldsCounter)
342 throws Exception {
343
344 String fieldName = ddmField.getName();
345
346 String fieldType = ddmStructure.getFieldType(fieldName);
347 String indexType = ddmStructure.getFieldProperty(
348 fieldName, "indexType");
349
350 dynamicElementElement.addAttribute(
351 "type", _ddmTypesToJournalTypes.get(fieldType));
352 dynamicElementElement.addAttribute("index-type", indexType);
353
354 for (Locale locale : ddmField.getAvailableLocales()) {
355 Element dynamicContentElement = dynamicElementElement.addElement(
356 "dynamic-content");
357
358 dynamicContentElement.addAttribute(
359 "language-id", LocaleUtil.toLanguageId(locale));
360
361 int count = ddmFieldsCounter.get(fieldName);
362
363 Serializable fieldValue = ddmField.getValue(locale, count);
364
365 updateDynamicContentValue(
366 dynamicContentElement, fieldType, String.valueOf(fieldValue));
367 }
368
369 ddmFieldsCounter.incrementKey(fieldName);
370 }
371
372 protected static void updateContentDynamicElement(
373 Element dynamicElementElement, DDMStructure ddmStructure,
374 Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
375 throws Exception {
376
377 String fieldName = dynamicElementElement.attributeValue("name");
378
379 for (String childFieldName :
380 ddmStructure.getChildrenFieldNames(fieldName)) {
381
382 int count = ddmFieldsCounter.get(fieldName);
383
384 int repetitions = countFieldRepetition(
385 ddmFields, childFieldName, fieldName, count);
386
387 for (int i = 0; i < repetitions; i++) {
388 Element childDynamicElementElement =
389 dynamicElementElement.addElement("dynamic-element");
390
391 childDynamicElementElement.addAttribute("name", childFieldName);
392
393 updateContentDynamicElement(
394 childDynamicElementElement, ddmStructure, ddmFields,
395 ddmFieldsCounter);
396 }
397 }
398
399 updateContentDynamicElement(
400 dynamicElementElement, ddmStructure, ddmFields.get(fieldName),
401 ddmFieldsCounter);
402 }
403
404 protected static void updateDynamicContentValue(
405 Element dynamicContentElement, String fieldType, String fieldValue)
406 throws Exception {
407
408 if (DDMImpl.TYPE_CHECKBOX.equals(fieldType)) {
409 if (fieldValue.equals(Boolean.FALSE.toString())) {
410 fieldValue = StringPool.BLANK;
411 }
412
413 dynamicContentElement.addCDATA(fieldValue);
414 }
415 else if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(fieldType)) {
416 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
417 fieldValue);
418
419 String uuid = jsonObject.getString("uuid");
420 long groupId = jsonObject.getLong("groupId");
421
422 FileEntry fileEntry =
423 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
424 uuid, groupId);
425
426 fieldValue = DLUtil.getPreviewURL(
427 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
428 false, true);
429
430 dynamicContentElement.addCDATA(fieldValue);
431 }
432 else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(fieldType)) {
433 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
434 fieldValue);
435
436 String layoutId = jsonObject.getString("layoutId");
437
438 boolean privateLayout = jsonObject.getBoolean("privateLayout");
439
440 if (privateLayout) {
441 fieldValue = layoutId.concat(StringPool.AT).concat("private");
442 }
443 else {
444 fieldValue = layoutId.concat(StringPool.AT).concat("public");
445 }
446
447 dynamicContentElement.addCDATA(fieldValue);
448 }
449 else if (DDMImpl.TYPE_SELECT.equals(fieldType)) {
450 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(fieldValue);
451
452 if (jsonArray.length() > 1) {
453 for (int i = 0; i <jsonArray.length(); i++) {
454 Element optionElement = dynamicContentElement.addElement(
455 "option");
456
457 optionElement.addCDATA(jsonArray.getString(i));
458 }
459 }
460 else {
461 dynamicContentElement.addCDATA(jsonArray.getString(0));
462 }
463 }
464 else {
465 dynamicContentElement.addCDATA(fieldValue);
466 }
467 }
468
469 protected static void updateFieldsDisplay(
470 Fields ddmFields, String fieldName) {
471
472 String fieldsDisplayValue =
473 fieldName.concat(DDMImpl.INSTANCE_SEPARATOR).concat(
474 PwdGenerator.getPassword());
475
476 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
477
478 String[] fieldsDisplayValues = StringUtil.split(
479 (String)fieldsDisplayField.getValue());
480
481 fieldsDisplayValues = ArrayUtil.append(
482 fieldsDisplayValues, fieldsDisplayValue);
483
484 fieldsDisplayField.setValue(StringUtil.merge(fieldsDisplayValues));
485 }
486
487 protected static void updateXSDDynamicElement(Element element) {
488 Locale defaultLocale = LocaleUtil.getDefault();
489
490 String name = element.attributeValue("name");
491 String type = element.attributeValue("type");
492
493 Element metadataElement = element.element("meta-data");
494
495 if (metadataElement == null) {
496 metadataElement = element.addElement("meta-data");
497 }
498
499 if (type.equals("multi-list")) {
500 element.addAttribute("multiple", "true");
501 }
502 else if (type.equals("selection_break")) {
503 Element parentElement = element.getParent();
504
505 parentElement.remove(element);
506
507 return;
508 }
509 else {
510 Element parentElement = element.getParent();
511
512 String parentType = parentElement.attributeValue("type");
513
514 if ((parentType != null) && parentType.equals("select")) {
515 metadataElement.addAttribute(
516 "locale", defaultLocale.toString());
517
518 addMetadataAttribute(metadataElement, "label", name);
519
520 element.addAttribute(
521 "name", "option" + PwdGenerator.getPassword(4));
522 element.addAttribute("type", "option");
523 element.addAttribute("value", type);
524
525 return;
526 }
527 }
528
529 String indexType = StringPool.BLANK;
530
531 Attribute indexTypeAttribute = element.attribute("index-type");
532
533 if (indexTypeAttribute != null) {
534 indexType = indexTypeAttribute.getValue();
535
536 element.remove(indexTypeAttribute);
537 }
538
539 element.remove(element.attribute("type"));
540
541 element.addAttribute("dataType", _ddmDataTypes.get(type));
542 element.addAttribute("indexType", indexType);
543
544 String required = "false";
545
546 XPath xPathSelector = SAXReaderUtil.createXPath(
547 "entry[@name='required']");
548
549 Element requiredElement = (Element)xPathSelector.selectSingleNode(
550 metadataElement);
551
552 if (requiredElement != null) {
553 required = requiredElement.getText();
554 }
555
556 element.addAttribute("required", required);
557
558 element.addAttribute("showLabel", "true");
559
560 String newType = _journalTypesToDDMTypes.get(type);
561
562 element.addAttribute("type", newType);
563
564 if (newType.startsWith("ddm")) {
565 element.addAttribute("fieldNamespace", "ddm");
566 }
567
568 metadataElement.addAttribute("locale", defaultLocale.toString());
569
570 List<Element> entryElements = metadataElement.elements();
571
572 if (entryElements.isEmpty()) {
573 addMetadataAttribute(metadataElement, "label", name);
574 }
575 else {
576 for (Element entryElement : entryElements) {
577 String oldEntryName = entryElement.attributeValue("name");
578
579 String newEntryName = _ddmMetadataAttributes.get(oldEntryName);
580
581 if (newEntryName == null) {
582 metadataElement.remove(entryElement);
583 }
584 else {
585 entryElement.addAttribute("name", newEntryName);
586 }
587 }
588 }
589
590 if (newType.equals("ddm-date") || newType.equals("ddm-decimal") ||
591 newType.equals("ddm-integer") ||
592 newType.equals("ddm-link-to-page") ||
593 newType.equals("ddm-number") || newType.equals("ddm-text-html") ||
594 newType.equals("text") || newType.equals("textarea")) {
595
596 element.addAttribute("width", "25");
597 }
598 else if (newType.equals("wcm-image")) {
599 element.addAttribute("fieldNamespace", "wcm");
600 element.addAttribute("readOnly", "false");
601 }
602
603 List<Element> dynamicElementElements = element.elements(
604 "dynamic-element");
605
606 for (Element dynamicElementElement : dynamicElementElements) {
607 updateXSDDynamicElement(dynamicElementElement);
608 }
609 }
610
611 private static Map<String, String> _ddmDataTypes =
612 new HashMap<String, String>();
613 private static Map<String, String> _ddmMetadataAttributes =
614 new HashMap<String, String>();
615 private static Map<String, String> _ddmTypesToJournalTypes =
616 new HashMap<String, String>();
617 private static Map<String, String> _journalTypesToDDMTypes =
618 new HashMap<String, String>();
619
620 static {
621 _ddmDataTypes.put("boolean", "boolean");
622 _ddmDataTypes.put("document_library", "document-library");
623 _ddmDataTypes.put("image", "image");
624 _ddmDataTypes.put("link_to_layout", "link-to-page");
625 _ddmDataTypes.put("list", "string");
626 _ddmDataTypes.put("multi-list", "string");
627 _ddmDataTypes.put("text", "string");
628 _ddmDataTypes.put("text_area", "html");
629 _ddmDataTypes.put("text_box", "string");
630
631 _ddmMetadataAttributes.put("instructions", "tip");
632 _ddmMetadataAttributes.put("label", "label");
633 _ddmMetadataAttributes.put("predefinedValue", "predefinedValue");
634
635 _ddmTypesToJournalTypes.put("checkbox", "boolean");
636 _ddmTypesToJournalTypes.put("ddm-documentlibrary", "document_library");
637 _ddmTypesToJournalTypes.put("ddm-link-to-page", "link_to_layout");
638 _ddmTypesToJournalTypes.put("ddm-text-html", "text_area");
639 _ddmTypesToJournalTypes.put("select", "list");
640 _ddmTypesToJournalTypes.put("text", "text");
641 _ddmTypesToJournalTypes.put("textarea", "text_box");
642 _ddmTypesToJournalTypes.put("wcm-image", "image");
643
644 _journalTypesToDDMTypes.put("boolean", "checkbox");
645 _journalTypesToDDMTypes.put("document_library", "ddm-documentlibrary");
646 _journalTypesToDDMTypes.put("image", "wcm-image");
647 _journalTypesToDDMTypes.put("link_to_layout", "ddm-link-to-page");
648 _journalTypesToDDMTypes.put("list", "select");
649 _journalTypesToDDMTypes.put("multi-list", "select");
650 _journalTypesToDDMTypes.put("text", "text");
651 _journalTypesToDDMTypes.put("text_area", "ddm-text-html");
652 _journalTypesToDDMTypes.put("text_box", "textarea");
653 }
654
655 }