001
014
015 package com.liferay.portlet.dynamicdatamapping.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
019 import com.liferay.portal.kernel.dao.orm.QueryUtil;
020 import com.liferay.portal.kernel.exception.PortalException;
021 import com.liferay.portal.kernel.exception.SystemException;
022 import com.liferay.portal.kernel.executor.PortalExecutorManagerUtil;
023 import com.liferay.portal.kernel.language.LanguageUtil;
024 import com.liferay.portal.kernel.log.Log;
025 import com.liferay.portal.kernel.log.LogFactoryUtil;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.search.SearchException;
029 import com.liferay.portal.kernel.systemevent.SystemEvent;
030 import com.liferay.portal.kernel.util.ArrayUtil;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.GroupThreadLocal;
033 import com.liferay.portal.kernel.util.HtmlUtil;
034 import com.liferay.portal.kernel.util.LocaleUtil;
035 import com.liferay.portal.kernel.util.OrderByComparator;
036 import com.liferay.portal.kernel.util.StringPool;
037 import com.liferay.portal.kernel.util.StringUtil;
038 import com.liferay.portal.kernel.util.Validator;
039 import com.liferay.portal.kernel.xml.Document;
040 import com.liferay.portal.kernel.xml.DocumentException;
041 import com.liferay.portal.kernel.xml.Element;
042 import com.liferay.portal.kernel.xml.Node;
043 import com.liferay.portal.kernel.xml.SAXReaderUtil;
044 import com.liferay.portal.kernel.xml.XPath;
045 import com.liferay.portal.model.Group;
046 import com.liferay.portal.model.ResourceConstants;
047 import com.liferay.portal.model.SystemEventConstants;
048 import com.liferay.portal.model.User;
049 import com.liferay.portal.security.auth.CompanyThreadLocal;
050 import com.liferay.portal.service.ServiceContext;
051 import com.liferay.portal.util.PortalUtil;
052 import com.liferay.portal.util.PropsValues;
053 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
054 import com.liferay.portlet.dynamicdatamapping.RequiredStructureException;
055 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateElementException;
056 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateStructureKeyException;
057 import com.liferay.portlet.dynamicdatamapping.StructureNameException;
058 import com.liferay.portlet.dynamicdatamapping.StructureXsdException;
059 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
060 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
061 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
062 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
063 import com.liferay.portlet.dynamicdatamapping.service.base.DDMStructureLocalServiceBaseImpl;
064 import com.liferay.portlet.dynamicdatamapping.util.DDMTemplateHelperUtil;
065 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
066
067 import java.io.IOException;
068
069 import java.util.ArrayList;
070 import java.util.Date;
071 import java.util.HashSet;
072 import java.util.List;
073 import java.util.Locale;
074 import java.util.Map;
075 import java.util.Set;
076
077
102 public class DDMStructureLocalServiceImpl
103 extends DDMStructureLocalServiceBaseImpl {
104
105
134 @Override
135 public DDMStructure addStructure(
136 long userId, long groupId, long parentStructureId, long classNameId,
137 String structureKey, Map<Locale, String> nameMap,
138 Map<Locale, String> descriptionMap, String xsd, String storageType,
139 int type, ServiceContext serviceContext)
140 throws PortalException, SystemException {
141
142
143
144 User user = userPersistence.findByPrimaryKey(userId);
145
146 if (Validator.isNull(structureKey)) {
147 structureKey = String.valueOf(counterLocalService.increment());
148 }
149 else {
150 structureKey = StringUtil.toUpperCase(structureKey.trim());
151 }
152
153 try {
154 xsd = DDMXMLUtil.validateXML(xsd);
155 xsd = DDMXMLUtil.formatXML(xsd);
156 }
157 catch (Exception e) {
158 throw new StructureXsdException(e);
159 }
160
161 Date now = new Date();
162
163 validate(
164 groupId, parentStructureId, classNameId, structureKey, nameMap,
165 xsd);
166
167 long structureId = counterLocalService.increment();
168
169 DDMStructure structure = ddmStructurePersistence.create(structureId);
170
171 structure.setUuid(serviceContext.getUuid());
172 structure.setGroupId(groupId);
173 structure.setCompanyId(user.getCompanyId());
174 structure.setUserId(user.getUserId());
175 structure.setUserName(user.getFullName());
176 structure.setCreateDate(serviceContext.getCreateDate(now));
177 structure.setModifiedDate(serviceContext.getModifiedDate(now));
178 structure.setParentStructureId(parentStructureId);
179 structure.setClassNameId(classNameId);
180 structure.setStructureKey(structureKey);
181 structure.setNameMap(nameMap);
182 structure.setDescriptionMap(descriptionMap);
183 structure.setXsd(xsd);
184 structure.setStorageType(storageType);
185 structure.setType(type);
186
187 ddmStructurePersistence.update(structure);
188
189
190
191 if (serviceContext.isAddGroupPermissions() ||
192 serviceContext.isAddGuestPermissions()) {
193
194 addStructureResources(
195 structure, serviceContext.isAddGroupPermissions(),
196 serviceContext.isAddGuestPermissions());
197 }
198 else {
199 addStructureResources(
200 structure, serviceContext.getGroupPermissions(),
201 serviceContext.getGuestPermissions());
202 }
203
204 return structure;
205 }
206
207
228 @Override
229 public DDMStructure addStructure(
230 long userId, long groupId, long classNameId,
231 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
232 String xsd, ServiceContext serviceContext)
233 throws PortalException, SystemException {
234
235 return addStructure(
236 userId, groupId, DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
237 classNameId, null, nameMap, descriptionMap, xsd,
238 PropsValues.DYNAMIC_DATA_LISTS_STORAGE_TYPE,
239 DDMStructureConstants.TYPE_DEFAULT, serviceContext);
240 }
241
242
271 @Override
272 public DDMStructure addStructure(
273 long userId, long groupId, String parentStructureKey,
274 long classNameId, String structureKey, Map<Locale, String> nameMap,
275 Map<Locale, String> descriptionMap, String xsd, String storageType,
276 int type, ServiceContext serviceContext)
277 throws PortalException, SystemException {
278
279 DDMStructure parentStructure = fetchStructure(
280 groupId, classNameId, parentStructureKey);
281
282 long parentStructureId =
283 DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID;
284
285 if (parentStructure != null) {
286 parentStructureId = parentStructure.getStructureId();
287 }
288
289 return addStructure(
290 userId, groupId, parentStructureId, classNameId, structureKey,
291 nameMap, descriptionMap, xsd, storageType, type, serviceContext);
292 }
293
294
303 @Override
304 public void addStructureResources(
305 DDMStructure structure, boolean addGroupPermissions,
306 boolean addGuestPermissions)
307 throws PortalException, SystemException {
308
309 resourceLocalService.addResources(
310 structure.getCompanyId(), structure.getGroupId(),
311 structure.getUserId(), DDMStructure.class.getName(),
312 structure.getStructureId(), false, addGroupPermissions,
313 addGuestPermissions);
314 }
315
316
325 @Override
326 public void addStructureResources(
327 DDMStructure structure, String[] groupPermissions,
328 String[] guestPermissions)
329 throws PortalException, SystemException {
330
331 resourceLocalService.addModelResources(
332 structure.getCompanyId(), structure.getGroupId(),
333 structure.getUserId(), DDMStructure.class.getName(),
334 structure.getStructureId(), groupPermissions, guestPermissions);
335 }
336
337
354 @Override
355 public DDMStructure copyStructure(
356 long userId, long structureId, Map<Locale, String> nameMap,
357 Map<Locale, String> descriptionMap, ServiceContext serviceContext)
358 throws PortalException, SystemException {
359
360 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
361 structureId);
362
363 return addStructure(
364 userId, structure.getGroupId(), structure.getParentStructureId(),
365 structure.getClassNameId(), null, nameMap, descriptionMap,
366 structure.getXsd(), structure.getStorageType(), structure.getType(),
367 serviceContext);
368 }
369
370 @Override
371 public DDMStructure copyStructure(
372 long userId, long structureId, ServiceContext serviceContext)
373 throws PortalException, SystemException {
374
375 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
376 structureId);
377
378 return addStructure(
379 userId, structure.getGroupId(), structure.getParentStructureId(),
380 structure.getClassNameId(), null, structure.getNameMap(),
381 structure.getDescriptionMap(), structure.getXsd(),
382 structure.getStorageType(), structure.getType(), serviceContext);
383 }
384
385
397 @Override
398 @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
399 public void deleteStructure(DDMStructure structure)
400 throws PortalException, SystemException {
401
402 if (!GroupThreadLocal.isDeleteInProcess()) {
403 if (ddmStructureLinkPersistence.countByStructureId(
404 structure.getStructureId()) > 0) {
405
406 throw new RequiredStructureException(
407 RequiredStructureException.REFERENCED_STRUCTURE_LINK);
408 }
409
410 if (ddmStructurePersistence.countByParentStructureId(
411 structure.getStructureId()) > 0) {
412
413 throw new RequiredStructureException(
414 RequiredStructureException.REFERENCED_STRUCTURE);
415 }
416
417 long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
418
419 if (ddmTemplatePersistence.countByG_C_C(
420 structure.getGroupId(), classNameId,
421 structure.getPrimaryKey()) > 0) {
422
423 throw new RequiredStructureException(
424 RequiredStructureException.REFERENCED_TEMPLATE);
425 }
426 }
427
428
429
430 ddmStructurePersistence.remove(structure);
431
432
433
434 resourceLocalService.deleteResource(
435 structure.getCompanyId(), DDMStructure.class.getName(),
436 ResourceConstants.SCOPE_INDIVIDUAL, structure.getStructureId());
437 }
438
439
451 @Override
452 public void deleteStructure(long structureId)
453 throws PortalException, SystemException {
454
455 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
456 structureId);
457
458 ddmStructureLocalService.deleteStructure(structure);
459 }
460
461
476 @Override
477 public void deleteStructure(
478 long groupId, long classNameId, String structureKey)
479 throws PortalException, SystemException {
480
481 structureKey = getStructureKey(structureKey);
482
483 DDMStructure structure = ddmStructurePersistence.findByG_C_S(
484 groupId, classNameId, structureKey);
485
486 ddmStructureLocalService.deleteStructure(structure);
487 }
488
489
502 @Override
503 public void deleteStructures(long groupId)
504 throws PortalException, SystemException {
505
506 List<DDMStructure> structures = ddmStructurePersistence.findByGroupId(
507 groupId);
508
509 deleteStructures(structures);
510 }
511
512 @Override
513 public void deleteStructures(long groupId, long classNameId)
514 throws PortalException, SystemException {
515
516 List<DDMStructure> structures = ddmStructurePersistence.findByG_C(
517 groupId, classNameId);
518
519 deleteStructures(structures);
520 }
521
522
530 @Override
531 public DDMStructure fetchStructure(long structureId)
532 throws SystemException {
533
534 return ddmStructurePersistence.fetchByPrimaryKey(structureId);
535 }
536
537
549 @Override
550 public DDMStructure fetchStructure(
551 long groupId, long classNameId, String structureKey)
552 throws SystemException {
553
554 structureKey = getStructureKey(structureKey);
555
556 return ddmStructurePersistence.fetchByG_C_S(
557 groupId, classNameId, structureKey);
558 }
559
560
581 @Override
582 public DDMStructure fetchStructure(
583 long groupId, long classNameId, String structureKey,
584 boolean includeGlobalStructures)
585 throws PortalException, SystemException {
586
587 structureKey = getStructureKey(structureKey);
588
589 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
590 groupId, classNameId, structureKey);
591
592 if ((structure != null) || !includeGlobalStructures) {
593 return structure;
594 }
595
596 Group group = groupPersistence.findByPrimaryKey(groupId);
597
598 Group companyGroup = groupLocalService.getCompanyGroup(
599 group.getCompanyId());
600
601 return ddmStructurePersistence.fetchByG_C_S(
602 companyGroup.getGroupId(), classNameId, structureKey);
603 }
604
605
609 @Override
610 public List<DDMStructure> getClassStructures(long classNameId)
611 throws SystemException {
612
613 return ddmStructurePersistence.findByClassNameId(classNameId);
614 }
615
616
620 @Override
621 public List<DDMStructure> getClassStructures(
622 long classNameId, int start, int end)
623 throws SystemException {
624
625 return ddmStructurePersistence.findByClassNameId(
626 classNameId, start, end);
627 }
628
629
638 @Override
639 public List<DDMStructure> getClassStructures(
640 long companyId, long classNameId)
641 throws SystemException {
642
643 return ddmStructurePersistence.findByC_C(companyId, classNameId);
644 }
645
646
668 @Override
669 public List<DDMStructure> getClassStructures(
670 long companyId, long classNameId, int start, int end)
671 throws SystemException {
672
673 return ddmStructurePersistence.findByC_C(
674 companyId, classNameId, start, end);
675 }
676
677
689 @Override
690 public List<DDMStructure> getClassStructures(
691 long companyId, long classNameId,
692 OrderByComparator orderByComparator)
693 throws SystemException {
694
695 return ddmStructurePersistence.findByC_C(
696 companyId, classNameId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
697 orderByComparator);
698 }
699
700
704 @Override
705 public List<DDMStructure> getClassStructures(
706 long classNameId, OrderByComparator orderByComparator)
707 throws SystemException {
708
709 return ddmStructurePersistence.findByClassNameId(
710 classNameId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
711 orderByComparator);
712 }
713
714
722 @Override
723 public List<DDMStructure> getDLFileEntryTypeStructures(
724 long dlFileEntryTypeId)
725 throws SystemException {
726
727 return dlFileEntryTypePersistence.getDDMStructures(dlFileEntryTypeId);
728 }
729
730
738 @Override
739 public DDMStructure getStructure(long structureId)
740 throws PortalException, SystemException {
741
742 return ddmStructurePersistence.findByPrimaryKey(structureId);
743 }
744
745
757 @Override
758 public DDMStructure getStructure(
759 long groupId, long classNameId, String structureKey)
760 throws PortalException, SystemException {
761
762 structureKey = getStructureKey(structureKey);
763
764 return ddmStructurePersistence.findByG_C_S(
765 groupId, classNameId, structureKey);
766 }
767
768
788 @Override
789 public DDMStructure getStructure(
790 long groupId, long classNameId, String structureKey,
791 boolean includeGlobalStructures)
792 throws PortalException, SystemException {
793
794 structureKey = getStructureKey(structureKey);
795
796 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
797 groupId, classNameId, structureKey);
798
799 if (structure != null) {
800 return structure;
801 }
802
803 if (!includeGlobalStructures) {
804 throw new NoSuchStructureException(
805 "No DDMStructure exists with the structure key " +
806 structureKey);
807 }
808
809 Group group = groupPersistence.findByPrimaryKey(groupId);
810
811 Group companyGroup = groupLocalService.getCompanyGroup(
812 group.getCompanyId());
813
814 return ddmStructurePersistence.findByG_C_S(
815 companyGroup.getGroupId(), classNameId, structureKey);
816 }
817
818
827 @Override
828 public List<DDMStructure> getStructure(
829 long groupId, String name, String description)
830 throws SystemException {
831
832 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
833 }
834
835
838 @Override
839 public List<DDMStructure> getStructureEntries() throws SystemException {
840 return getStructures();
841 }
842
843
846 @Override
847 public List<DDMStructure> getStructureEntries(long groupId)
848 throws SystemException {
849
850 return getStructures(groupId);
851 }
852
853
857 @Override
858 public List<DDMStructure> getStructureEntries(
859 long groupId, int start, int end)
860 throws SystemException {
861
862 return getStructures(groupId, start, end);
863 }
864
865
871 @Override
872 public List<DDMStructure> getStructures() throws SystemException {
873 return ddmStructurePersistence.findAll();
874 }
875
876
883 @Override
884 public List<DDMStructure> getStructures(long groupId)
885 throws SystemException {
886
887 return ddmStructurePersistence.findByGroupId(groupId);
888 }
889
890
910 @Override
911 public List<DDMStructure> getStructures(long groupId, int start, int end)
912 throws SystemException {
913
914 return ddmStructurePersistence.findByGroupId(groupId, start, end);
915 }
916
917
926 @Override
927 public List<DDMStructure> getStructures(long groupId, long classNameId)
928 throws SystemException {
929
930 return ddmStructurePersistence.findByG_C(groupId, classNameId);
931 }
932
933
956 @Override
957 public List<DDMStructure> getStructures(
958 long groupId, long classNameId, int start, int end)
959 throws SystemException {
960
961 return ddmStructurePersistence.findByG_C(
962 groupId, classNameId, start, end);
963 }
964
965
990 @Override
991 public List<DDMStructure> getStructures(
992 long groupId, long classNameId, int start, int end,
993 OrderByComparator orderByComparator)
994 throws SystemException {
995
996 return ddmStructurePersistence.findByG_C(
997 groupId, classNameId, start, end, orderByComparator);
998 }
999
1000 @Override
1001 public List<DDMStructure> getStructures(
1002 long groupId, String name, String description)
1003 throws SystemException {
1004
1005 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
1006 }
1007
1008
1015 @Override
1016 public List<DDMStructure> getStructures(long[] groupIds)
1017 throws SystemException {
1018
1019 return ddmStructurePersistence.findByGroupId(groupIds);
1020 }
1021
1022
1032 @Override
1033 public List<DDMStructure> getStructures(long[] groupIds, long classNameId)
1034 throws SystemException {
1035
1036 return ddmStructurePersistence.findByG_C(groupIds, classNameId);
1037 }
1038
1039
1062 @Override
1063 public List<DDMStructure> getStructures(
1064 long[] groupIds, long classNameId, int start, int end)
1065 throws SystemException {
1066
1067 return ddmStructurePersistence.findByG_C(
1068 groupIds, classNameId, start, end);
1069 }
1070
1071
1078 @Override
1079 public int getStructuresCount(long groupId) throws SystemException {
1080 return ddmStructurePersistence.countByGroupId(groupId);
1081 }
1082
1083
1092 @Override
1093 public int getStructuresCount(long groupId, long classNameId)
1094 throws SystemException {
1095
1096 return ddmStructurePersistence.countByG_C(groupId, classNameId);
1097 }
1098
1099
1109 @Override
1110 public int getStructuresCount(long[] groupIds, long classNameId)
1111 throws SystemException {
1112
1113 return ddmStructurePersistence.countByG_C(groupIds, classNameId);
1114 }
1115
1116
1145 @Override
1146 public List<DDMStructure> search(
1147 long companyId, long[] groupIds, long[] classNameIds,
1148 String keywords, int start, int end,
1149 OrderByComparator orderByComparator)
1150 throws SystemException {
1151
1152 return ddmStructureFinder.findByKeywords(
1153 companyId, groupIds, classNameIds, keywords, start, end,
1154 orderByComparator);
1155 }
1156
1157
1192 @Override
1193 public List<DDMStructure> search(
1194 long companyId, long[] groupIds, long[] classNameIds, String name,
1195 String description, String storageType, int type,
1196 boolean andOperator, int start, int end,
1197 OrderByComparator orderByComparator)
1198 throws SystemException {
1199
1200 return ddmStructureFinder.findByC_G_C_N_D_S_T(
1201 companyId, groupIds, classNameIds, name, description, storageType,
1202 type, andOperator, start, end, orderByComparator);
1203 }
1204
1205
1218 @Override
1219 public int searchCount(
1220 long companyId, long[] groupIds, long[] classNameIds,
1221 String keywords)
1222 throws SystemException {
1223
1224 return ddmStructureFinder.countByKeywords(
1225 companyId, groupIds, classNameIds, keywords);
1226 }
1227
1228
1248 @Override
1249 public int searchCount(
1250 long companyId, long[] groupIds, long[] classNameIds, String name,
1251 String description, String storageType, int type,
1252 boolean andOperator)
1253 throws SystemException {
1254
1255 return ddmStructureFinder.countByC_G_C_N_D_S_T(
1256 companyId, groupIds, classNameIds, name, description, storageType,
1257 type, andOperator);
1258 }
1259
1260
1281 @Override
1282 public DDMStructure updateStructure(
1283 long groupId, long parentStructureId, long classNameId,
1284 String structureKey, Map<Locale, String> nameMap,
1285 Map<Locale, String> descriptionMap, String xsd,
1286 ServiceContext serviceContext)
1287 throws PortalException, SystemException {
1288
1289 structureKey = getStructureKey(structureKey);
1290
1291 DDMStructure structure = ddmStructurePersistence.findByG_C_S(
1292 groupId, classNameId, structureKey);
1293
1294 return doUpdateStructure(
1295 parentStructureId, nameMap, descriptionMap, xsd, serviceContext,
1296 structure);
1297 }
1298
1299
1316 @Override
1317 public DDMStructure updateStructure(
1318 long structureId, long parentStructureId,
1319 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
1320 String xsd, ServiceContext serviceContext)
1321 throws PortalException, SystemException {
1322
1323 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
1324 structureId);
1325
1326 return doUpdateStructure(
1327 parentStructureId, nameMap, descriptionMap, xsd, serviceContext,
1328 structure);
1329 }
1330
1331
1344 @Override
1345 public DDMStructure updateXSD(
1346 long structureId, String xsd, ServiceContext serviceContext)
1347 throws PortalException, SystemException {
1348
1349 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
1350 structureId);
1351
1352 return doUpdateStructure(
1353 structure.getParentStructureId(), structure.getNameMap(),
1354 structure.getDescriptionMap(), xsd, serviceContext, structure);
1355 }
1356
1357
1374 @Override
1375 public void updateXSDFieldMetadata(
1376 long structureId, String fieldName, String metadataEntryName,
1377 String metadataEntryValue, ServiceContext serviceContext)
1378 throws PortalException, SystemException {
1379
1380 DDMStructure ddmStructure = fetchDDMStructure(structureId);
1381
1382 if (ddmStructure == null) {
1383 return;
1384 }
1385
1386 String xsd = ddmStructure.getXsd();
1387
1388 try {
1389 Document document = SAXReaderUtil.read(xsd);
1390
1391 Element rootElement = document.getRootElement();
1392
1393 List<Element> dynamicElementElements = rootElement.elements(
1394 "dynamic-element");
1395
1396 for (Element dynamicElementElement : dynamicElementElements) {
1397 String dynamicElementElementFieldName = GetterUtil.getString(
1398 dynamicElementElement.attributeValue("name"));
1399
1400 if (!dynamicElementElementFieldName.equals(fieldName)) {
1401 continue;
1402 }
1403
1404 List<Element> metadataElements = dynamicElementElement.elements(
1405 "meta-data");
1406
1407 for (Element metadataElement : metadataElements) {
1408 List<Element> metadataEntryElements =
1409 metadataElement.elements();
1410
1411 for (Element metadataEntryElement : metadataEntryElements) {
1412 String metadataEntryElementName = GetterUtil.getString(
1413 metadataEntryElement.attributeValue("name"));
1414
1415 if (metadataEntryElementName.equals(
1416 metadataEntryName)) {
1417
1418 metadataEntryElement.setText(metadataEntryValue);
1419 }
1420 }
1421 }
1422 }
1423
1424 updateXSD(structureId, document.asXML(), serviceContext);
1425 }
1426 catch (DocumentException de) {
1427 throw new SystemException(de);
1428 }
1429 }
1430
1431 protected void appendNewStructureRequiredFields(
1432 DDMStructure structure, Document structureDocument,
1433 Document templateDocument) {
1434
1435 Element templateRootElement = templateDocument.getRootElement();
1436
1437 XPath structureXPath = SAXReaderUtil.createXPath(
1438 "
1439
1440 List<Node> structureNodes = structureXPath.selectNodes(
1441 structureDocument);
1442
1443 for (Node structureNode : structureNodes) {
1444 Element structureElement = (Element)structureNode;
1445
1446 String name = structureElement.attributeValue("name");
1447
1448 name = HtmlUtil.escapeXPathAttribute(name);
1449
1450 XPath templateXPath = SAXReaderUtil.createXPath(
1451 "
1452
1453 List<Node> matchingTemplateNodes = templateXPath.selectNodes(
1454 templateDocument);
1455
1456 if (matchingTemplateNodes.isEmpty()) {
1457 templateRootElement.add(structureElement.createCopy());
1458 }
1459 }
1460 }
1461
1462 protected Set<Long> deleteStructures(List<DDMStructure> structures)
1463 throws PortalException, SystemException {
1464
1465 Set<Long> deletedStructureIds = new HashSet<Long>();
1466
1467 for (DDMStructure structure : structures) {
1468 if (deletedStructureIds.contains(structure.getStructureId())) {
1469 continue;
1470 }
1471
1472 if (!GroupThreadLocal.isDeleteInProcess()) {
1473 List<DDMStructure> childDDMStructures =
1474 ddmStructurePersistence.findByParentStructureId(
1475 structure.getStructureId());
1476
1477 deletedStructureIds.addAll(
1478 deleteStructures(childDDMStructures));
1479 }
1480
1481 ddmStructureLocalService.deleteStructure(structure);
1482
1483 deletedStructureIds.add(structure.getStructureId());
1484 }
1485
1486 return deletedStructureIds;
1487 }
1488
1489 protected DDMStructure doUpdateStructure(
1490 long parentStructureId, Map<Locale, String> nameMap,
1491 Map<Locale, String> descriptionMap, String xsd,
1492 ServiceContext serviceContext, DDMStructure structure)
1493 throws PortalException, SystemException {
1494
1495 try {
1496 xsd = DDMXMLUtil.validateXML(xsd);
1497 xsd = DDMXMLUtil.formatXML(xsd);
1498 }
1499 catch (Exception e) {
1500 throw new StructureXsdException(e);
1501 }
1502
1503 String parentXsd = StringPool.BLANK;
1504
1505 DDMStructure parentStructure =
1506 ddmStructurePersistence.fetchByPrimaryKey(parentStructureId);
1507
1508 if (parentStructure != null) {
1509 parentXsd = parentStructure.getCompleteXsd();
1510 }
1511
1512 validate(nameMap, parentXsd, xsd);
1513
1514 structure.setModifiedDate(serviceContext.getModifiedDate(null));
1515 structure.setParentStructureId(parentStructureId);
1516 structure.setNameMap(nameMap);
1517 structure.setDescriptionMap(descriptionMap);
1518 structure.setXsd(xsd);
1519
1520 ddmStructurePersistence.update(structure);
1521
1522 syncStructureTemplatesFields(structure);
1523
1524 if (!serviceContext.isIndexingEnabled()) {
1525 return structure;
1526 }
1527
1528 final Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1529 structure.getClassName());
1530
1531 final List<Long> ddmStructureIds = getChildrenStructureIds(
1532 structure.getGroupId(), structure.getStructureId());
1533
1534 if (PropsValues.DYNAMIC_DATA_MAPPING_STRUCTURE_INDEX_WITH_THREAD) {
1535 ThreadPoolExecutor threadPoolExecutor =
1536 PortalExecutorManagerUtil.getPortalExecutor(
1537 DDMStructureLocalServiceImpl.class.getName());
1538
1539 Runnable runnable = new Runnable() {
1540
1541 @Override
1542 public void run() {
1543 try {
1544 indexer.reindexDDMStructures(ddmStructureIds);
1545 }
1546 catch (SearchException se) {
1547 throw new RuntimeException(se);
1548 }
1549 }
1550
1551 };
1552
1553 threadPoolExecutor.execute(runnable);
1554 }
1555 else {
1556 indexer.reindexDDMStructures(ddmStructureIds);
1557 }
1558
1559 return structure;
1560 }
1561
1562 protected void getChildrenStructureIds(
1563 List<Long> structureIds, long groupId, long parentStructureId)
1564 throws PortalException, SystemException {
1565
1566 List<DDMStructure> structures = ddmStructurePersistence.findByG_P(
1567 groupId, parentStructureId);
1568
1569 for (DDMStructure structure : structures) {
1570 structureIds.add(structure.getStructureId());
1571
1572 getChildrenStructureIds(
1573 structureIds, structure.getGroupId(),
1574 structure.getStructureId());
1575 }
1576 }
1577
1578 protected List<Long> getChildrenStructureIds(long groupId, long structureId)
1579 throws PortalException, SystemException {
1580
1581 List<Long> structureIds = new ArrayList<Long>();
1582
1583 getChildrenStructureIds(structureIds, groupId, structureId);
1584
1585 structureIds.add(0, structureId);
1586
1587 return structureIds;
1588 }
1589
1590 protected Set<String> getElementNames(Document document)
1591 throws PortalException {
1592
1593 Set<String> elementNames = new HashSet<String>();
1594
1595 XPath xPathSelector = SAXReaderUtil.createXPath("
1596
1597 List<Node> nodes = xPathSelector.selectNodes(document);
1598
1599 for (Node node : nodes) {
1600 Element element = (Element)node;
1601
1602 String name = StringUtil.toLowerCase(
1603 element.attributeValue("name"));
1604
1605 elementNames.add(name);
1606 }
1607
1608 return elementNames;
1609 }
1610
1611 protected String getStructureKey(String structureKey) {
1612 if (structureKey != null) {
1613 structureKey = structureKey.trim();
1614
1615 return StringUtil.toUpperCase(structureKey);
1616 }
1617
1618 return StringPool.BLANK;
1619 }
1620
1621 protected void syncStructureTemplatesFields(DDMStructure structure)
1622 throws PortalException, SystemException {
1623
1624 long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
1625
1626 List<DDMTemplate> templates = ddmTemplateLocalService.getTemplates(
1627 structure.getGroupId(), classNameId, structure.getStructureId(),
1628 DDMTemplateConstants.TEMPLATE_TYPE_FORM);
1629
1630 Document structureDocument = null;
1631
1632 try {
1633 structureDocument = SAXReaderUtil.read(structure.getXsd());
1634 }
1635 catch (DocumentException de) {
1636 if (_log.isWarnEnabled()) {
1637 _log.warn(de, de);
1638 }
1639
1640 return;
1641 }
1642
1643 for (DDMTemplate template : templates) {
1644 String script = template.getScript();
1645
1646 Document templateDocument = null;
1647
1648 try {
1649 templateDocument = SAXReaderUtil.read(script);
1650 }
1651 catch (DocumentException de) {
1652 if (_log.isWarnEnabled()) {
1653 _log.warn(de, de);
1654 }
1655
1656 continue;
1657 }
1658
1659 Element templateRootElement = templateDocument.getRootElement();
1660
1661 syncStructureTemplatesFields(
1662 structureDocument, template, templateRootElement);
1663
1664 appendNewStructureRequiredFields(
1665 structure, structureDocument, templateDocument);
1666
1667 try {
1668 script = DDMXMLUtil.formatXML(templateDocument.asXML());
1669 }
1670 catch (Exception e) {
1671 throw new StructureXsdException(e);
1672 }
1673
1674 template.setScript(script);
1675
1676 ddmTemplatePersistence.update(template);
1677 }
1678 }
1679
1680 protected void syncStructureTemplatesFields(
1681 Document structureDocument, DDMTemplate template,
1682 Element templateElement)
1683 throws PortalException, SystemException {
1684
1685 DDMStructure structure = DDMTemplateHelperUtil.fetchStructure(template);
1686
1687 List<Element> dynamicElementElements = templateElement.elements(
1688 "dynamic-element");
1689
1690 for (Element dynamicElementElement : dynamicElementElements) {
1691 String dataType = dynamicElementElement.attributeValue("dataType");
1692 String fieldName = dynamicElementElement.attributeValue("name");
1693
1694 if (Validator.isNull(dataType)) {
1695 continue;
1696 }
1697
1698 if (!structure.hasField(fieldName)) {
1699 templateElement.remove(dynamicElementElement);
1700
1701 continue;
1702 }
1703
1704 XPath structureXPath = SAXReaderUtil.createXPath(
1705 "
1706
1707 Element structureElement =
1708 (Element)structureXPath.selectSingleNode(
1709 structureDocument.getRootElement());
1710
1711 syncFieldOptions(structureElement, dynamicElementElement);
1712
1713 String mode = template.getMode();
1714
1715 if (mode.equals(DDMTemplateConstants.TEMPLATE_MODE_CREATE)) {
1716 boolean fieldRequired = structure.getFieldRequired(fieldName);
1717
1718 List<Element> metadataElements = dynamicElementElement.elements(
1719 "meta-data");
1720
1721 for (Element metadataElement : metadataElements) {
1722 for (Element metadataEntryElement :
1723 metadataElement.elements()) {
1724
1725 String attributeName =
1726 metadataEntryElement.attributeValue("name");
1727
1728 if (fieldRequired && attributeName.equals("required")) {
1729 metadataEntryElement.setText("true");
1730 }
1731 }
1732 }
1733 }
1734
1735 syncStructureTemplatesFields(
1736 structureDocument, template, dynamicElementElement);
1737 }
1738 }
1739
1740 protected void syncFieldOptions(
1741 Element structureElement, Element templateElement) {
1742
1743 if (structureElement == null) {
1744 return;
1745 }
1746
1747 String type = templateElement.attributeValue("type");
1748
1749 if (!(type.equals("select") || type.equals("radio"))) {
1750 return;
1751 }
1752
1753 List<Element> metadataElements = templateElement.elements("meta-data");
1754
1755 templateElement.clearContent();
1756
1757 List<Element> dynamicElementElements = structureElement.elements(
1758 "dynamic-element");
1759
1760 for (Element dynamicElement :dynamicElementElements) {
1761 templateElement.add(dynamicElement.createCopy());
1762 }
1763
1764 for (Element metadateElement : metadataElements) {
1765 templateElement.add(metadateElement.createCopy());
1766 }
1767 }
1768
1769 protected void validate(Document document) throws PortalException {
1770 XPath xPathSelector = SAXReaderUtil.createXPath("
1771
1772 List<Node> nodes = xPathSelector.selectNodes(document);
1773
1774 Set<String> elementNames = new HashSet<String>();
1775
1776 for (Node node : nodes) {
1777 Element element = (Element)node;
1778
1779 String name = StringUtil.toLowerCase(
1780 element.attributeValue("name"));
1781
1782 if (Validator.isNull(name)) {
1783 String formattedString = StringPool.BLANK;
1784
1785 try {
1786 formattedString = element.formattedString();
1787 }
1788 catch (IOException e) {
1789 }
1790
1791 throw new StructureXsdException(
1792 "Element must have a name attribute " + formattedString);
1793 }
1794
1795 if (name.startsWith(DDMStructureConstants.XSD_NAME_RESERVED)) {
1796 throw new StructureXsdException(
1797 "Element name " + name + " is reserved");
1798 }
1799
1800 if (elementNames.contains(name)) {
1801 throw new StructureDuplicateElementException(
1802 "Element with name " + name + " already exists");
1803 }
1804
1805 elementNames.add(name);
1806 }
1807 }
1808
1809 protected void validate(Document parentDocument, Document childDocument)
1810 throws PortalException {
1811
1812 Set<String> parentElementNames = getElementNames(parentDocument);
1813
1814 for (String childElementName : getElementNames(childDocument)) {
1815 if (parentElementNames.contains(childElementName)) {
1816 throw new StructureDuplicateElementException();
1817 }
1818 }
1819 }
1820
1821 protected void validate(
1822 long groupId, long parentStructureId, long classNameId,
1823 String structureKey, Map<Locale, String> nameMap, String xsd)
1824 throws PortalException, SystemException {
1825
1826 structureKey = getStructureKey(structureKey);
1827
1828 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
1829 groupId, classNameId, structureKey);
1830
1831 if (structure != null) {
1832 StructureDuplicateStructureKeyException sdske =
1833 new StructureDuplicateStructureKeyException();
1834
1835 sdske.setStructureKey(structure.getStructureKey());
1836
1837 throw sdske;
1838 }
1839
1840 String parentXsd = StringPool.BLANK;
1841
1842 DDMStructure parentStructure =
1843 ddmStructurePersistence.fetchByPrimaryKey(parentStructureId);
1844
1845 if (parentStructure != null) {
1846 parentXsd = parentStructure.getCompleteXsd();
1847 }
1848
1849 validate(nameMap, parentXsd, xsd);
1850 }
1851
1852 protected void validate(
1853 Map<Locale, String> nameMap, Locale contentDefaultLocale)
1854 throws PortalException {
1855
1856 String name = nameMap.get(contentDefaultLocale);
1857
1858 if (Validator.isNull(name)) {
1859 throw new StructureNameException(
1860 "Name is null for locale " +
1861 contentDefaultLocale.getDisplayName());
1862 }
1863
1864 Locale[] availableLocales = LanguageUtil.getAvailableLocales();
1865
1866 if (!ArrayUtil.contains(availableLocales, contentDefaultLocale)) {
1867 Long companyId = CompanyThreadLocal.getCompanyId();
1868
1869 LocaleException le = new LocaleException(
1870 LocaleException.TYPE_CONTENT,
1871 "The locale " + contentDefaultLocale +
1872 " is not available in company " + companyId);
1873
1874 le.setSourceAvailableLocales(new Locale[] {contentDefaultLocale});
1875 le.setTargetAvailableLocales(availableLocales);
1876
1877 throw le;
1878 }
1879 }
1880
1881 protected void validate(
1882 Map<Locale, String> nameMap, String parentXsd, String childXsd)
1883 throws PortalException {
1884
1885 try {
1886 Document document = SAXReaderUtil.read(childXsd);
1887
1888 Element rootElement = document.getRootElement();
1889
1890 Locale contentDefaultLocale = LocaleUtil.fromLanguageId(
1891 rootElement.attributeValue("default-locale"));
1892
1893 validate(nameMap, contentDefaultLocale);
1894
1895 validate(document);
1896
1897 if (Validator.isNotNull(parentXsd)) {
1898 Document parentDocument = SAXReaderUtil.read(parentXsd);
1899
1900 validate(parentDocument, document);
1901 }
1902 }
1903 catch (LocaleException le) {
1904 throw le;
1905 }
1906 catch (StructureDuplicateElementException sdee) {
1907 throw sdee;
1908 }
1909 catch (StructureNameException sne) {
1910 throw sne;
1911 }
1912 catch (StructureXsdException sxe) {
1913 throw sxe;
1914 }
1915 catch (Exception e) {
1916 throw new StructureXsdException(e);
1917 }
1918 }
1919
1920 private static Log _log = LogFactoryUtil.getLog(
1921 DDMStructureLocalServiceImpl.class);
1922
1923 }