001
014
015 package com.liferay.portlet.dynamicdatamapping.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.language.LanguageUtil;
021 import com.liferay.portal.kernel.search.Indexer;
022 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
023 import com.liferay.portal.kernel.systemevent.SystemEvent;
024 import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
025 import com.liferay.portal.kernel.util.ArrayUtil;
026 import com.liferay.portal.kernel.util.GroupThreadLocal;
027 import com.liferay.portal.kernel.util.LocaleUtil;
028 import com.liferay.portal.kernel.util.OrderByComparator;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.kernel.xml.Document;
033 import com.liferay.portal.kernel.xml.Element;
034 import com.liferay.portal.kernel.xml.Node;
035 import com.liferay.portal.kernel.xml.SAXReaderUtil;
036 import com.liferay.portal.kernel.xml.XPath;
037 import com.liferay.portal.model.ResourceConstants;
038 import com.liferay.portal.model.SystemEventConstants;
039 import com.liferay.portal.model.User;
040 import com.liferay.portal.security.auth.CompanyThreadLocal;
041 import com.liferay.portal.service.ServiceContext;
042 import com.liferay.portal.util.PortalUtil;
043 import com.liferay.portal.util.PropsValues;
044 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
045 import com.liferay.portlet.dynamicdatamapping.RequiredStructureException;
046 import com.liferay.portlet.dynamicdatamapping.StructureDefinitionException;
047 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateElementException;
048 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateStructureKeyException;
049 import com.liferay.portlet.dynamicdatamapping.StructureNameException;
050 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
051 import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
052 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
053 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
054 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
055 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
056 import com.liferay.portlet.dynamicdatamapping.service.base.DDMStructureLocalServiceBaseImpl;
057 import com.liferay.portlet.dynamicdatamapping.util.DDMFormTemplateSynchonizer;
058 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
059 import com.liferay.portlet.journal.model.JournalArticle;
060 import com.liferay.portlet.journal.model.JournalFolderConstants;
061
062 import java.util.ArrayList;
063 import java.util.Date;
064 import java.util.HashSet;
065 import java.util.List;
066 import java.util.Locale;
067 import java.util.Map;
068 import java.util.Set;
069 import java.util.concurrent.Callable;
070
071
096 public class DDMStructureLocalServiceImpl
097 extends DDMStructureLocalServiceBaseImpl {
098
099
127 @Override
128 public DDMStructure addStructure(
129 long userId, long groupId, long parentStructureId, long classNameId,
130 String structureKey, Map<Locale, String> nameMap,
131 Map<Locale, String> descriptionMap, String definition,
132 String storageType, int type, ServiceContext serviceContext)
133 throws PortalException {
134
135
136
137 User user = userPersistence.findByPrimaryKey(userId);
138
139 if (Validator.isNull(structureKey)) {
140 structureKey = String.valueOf(counterLocalService.increment());
141 }
142 else {
143 structureKey = StringUtil.toUpperCase(structureKey.trim());
144 }
145
146 try {
147 definition = DDMXMLUtil.validateXML(definition);
148 definition = DDMXMLUtil.formatXML(definition);
149 }
150 catch (Exception e) {
151 throw new StructureDefinitionException();
152 }
153
154 Date now = new Date();
155
156 validate(
157 groupId, parentStructureId, classNameId, structureKey, nameMap,
158 definition);
159
160 long structureId = counterLocalService.increment();
161
162 DDMStructure structure = ddmStructurePersistence.create(structureId);
163
164 structure.setUuid(serviceContext.getUuid());
165 structure.setGroupId(groupId);
166 structure.setCompanyId(user.getCompanyId());
167 structure.setUserId(user.getUserId());
168 structure.setUserName(user.getFullName());
169 structure.setCreateDate(serviceContext.getCreateDate(now));
170 structure.setModifiedDate(serviceContext.getModifiedDate(now));
171 structure.setParentStructureId(parentStructureId);
172 structure.setClassNameId(classNameId);
173 structure.setStructureKey(structureKey);
174 structure.setNameMap(nameMap);
175 structure.setDescriptionMap(descriptionMap);
176 structure.setDefinition(definition);
177 structure.setStorageType(storageType);
178 structure.setType(type);
179
180 ddmStructurePersistence.update(structure);
181
182
183
184 if (serviceContext.isAddGroupPermissions() ||
185 serviceContext.isAddGuestPermissions()) {
186
187 addStructureResources(
188 structure, serviceContext.isAddGroupPermissions(),
189 serviceContext.isAddGuestPermissions());
190 }
191 else {
192 addStructureResources(
193 structure, serviceContext.getGroupPermissions(),
194 serviceContext.getGuestPermissions());
195 }
196
197 return structure;
198 }
199
200
220 @Override
221 public DDMStructure addStructure(
222 long userId, long groupId, long classNameId,
223 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
224 String definition, ServiceContext serviceContext)
225 throws PortalException {
226
227 return addStructure(
228 userId, groupId, DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
229 classNameId, null, nameMap, descriptionMap, definition,
230 PropsValues.DYNAMIC_DATA_LISTS_STORAGE_TYPE,
231 DDMStructureConstants.TYPE_DEFAULT, serviceContext);
232 }
233
234
262 @Override
263 public DDMStructure addStructure(
264 long userId, long groupId, String parentStructureKey,
265 long classNameId, String structureKey, Map<Locale, String> nameMap,
266 Map<Locale, String> descriptionMap, String definition,
267 String storageType, int type, ServiceContext serviceContext)
268 throws PortalException {
269
270 DDMStructure parentStructure = fetchStructure(
271 groupId, classNameId, parentStructureKey);
272
273 long parentStructureId =
274 DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID;
275
276 if (parentStructure != null) {
277 parentStructureId = parentStructure.getStructureId();
278 }
279
280 return addStructure(
281 userId, groupId, parentStructureId, classNameId, structureKey,
282 nameMap, descriptionMap, definition, storageType, type,
283 serviceContext);
284 }
285
286
294 @Override
295 public void addStructureResources(
296 DDMStructure structure, boolean addGroupPermissions,
297 boolean addGuestPermissions)
298 throws PortalException {
299
300 resourceLocalService.addResources(
301 structure.getCompanyId(), structure.getGroupId(),
302 structure.getUserId(), DDMStructure.class.getName(),
303 structure.getStructureId(), false, addGroupPermissions,
304 addGuestPermissions);
305 }
306
307
315 @Override
316 public void addStructureResources(
317 DDMStructure structure, String[] groupPermissions,
318 String[] guestPermissions)
319 throws PortalException {
320
321 resourceLocalService.addModelResources(
322 structure.getCompanyId(), structure.getGroupId(),
323 structure.getUserId(), DDMStructure.class.getName(),
324 structure.getStructureId(), groupPermissions, guestPermissions);
325 }
326
327
343 @Override
344 public DDMStructure copyStructure(
345 long userId, long structureId, Map<Locale, String> nameMap,
346 Map<Locale, String> descriptionMap, ServiceContext serviceContext)
347 throws PortalException {
348
349 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
350 structureId);
351
352 return addStructure(
353 userId, structure.getGroupId(), structure.getParentStructureId(),
354 structure.getClassNameId(), null, nameMap, descriptionMap,
355 structure.getDefinition(), structure.getStorageType(),
356 structure.getType(), serviceContext);
357 }
358
359 @Override
360 public DDMStructure copyStructure(
361 long userId, long structureId, ServiceContext serviceContext)
362 throws PortalException {
363
364 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
365 structureId);
366
367 return addStructure(
368 userId, structure.getGroupId(), structure.getParentStructureId(),
369 structure.getClassNameId(), null, structure.getNameMap(),
370 structure.getDescriptionMap(), structure.getDefinition(),
371 structure.getStorageType(), structure.getType(), serviceContext);
372 }
373
374
385 @Override
386 @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
387 public void deleteStructure(DDMStructure structure) throws PortalException {
388 if (!GroupThreadLocal.isDeleteInProcess()) {
389 if (ddmStructureLinkPersistence.countByStructureId(
390 structure.getStructureId()) > 0) {
391
392 throw new RequiredStructureException(
393 RequiredStructureException.REFERENCED_STRUCTURE_LINK);
394 }
395
396 if (ddmStructurePersistence.countByParentStructureId(
397 structure.getStructureId()) > 0) {
398
399 throw new RequiredStructureException(
400 RequiredStructureException.REFERENCED_STRUCTURE);
401 }
402
403 long classNameId = classNameLocalService.getClassNameId(
404 DDMStructure.class);
405
406 if (ddmTemplatePersistence.countByG_C_C(
407 structure.getGroupId(), classNameId,
408 structure.getPrimaryKey()) > 0) {
409
410 throw new RequiredStructureException(
411 RequiredStructureException.REFERENCED_TEMPLATE);
412 }
413 }
414
415
416
417 ddmStructurePersistence.remove(structure);
418
419
420
421 resourceLocalService.deleteResource(
422 structure.getCompanyId(), DDMStructure.class.getName(),
423 ResourceConstants.SCOPE_INDIVIDUAL, structure.getStructureId());
424 }
425
426
437 @Override
438 public void deleteStructure(long structureId) throws PortalException {
439 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
440 structureId);
441
442 ddmStructureLocalService.deleteStructure(structure);
443 }
444
445
459 @Override
460 public void deleteStructure(
461 long groupId, long classNameId, String structureKey)
462 throws PortalException {
463
464 structureKey = getStructureKey(structureKey);
465
466 DDMStructure structure = ddmStructurePersistence.findByG_C_S(
467 groupId, classNameId, structureKey);
468
469 ddmStructureLocalService.deleteStructure(structure);
470 }
471
472
484 @Override
485 public void deleteStructures(long groupId) throws PortalException {
486 List<DDMStructure> structures = ddmStructurePersistence.findByGroupId(
487 groupId);
488
489 deleteStructures(structures);
490 }
491
492 @Override
493 public void deleteStructures(long groupId, long classNameId)
494 throws PortalException {
495
496 List<DDMStructure> structures = ddmStructurePersistence.findByG_C(
497 groupId, classNameId);
498
499 deleteStructures(structures);
500 }
501
502
509 @Override
510 public DDMStructure fetchStructure(long structureId) {
511 return ddmStructurePersistence.fetchByPrimaryKey(structureId);
512 }
513
514
525 @Override
526 public DDMStructure fetchStructure(
527 long groupId, long classNameId, String structureKey) {
528
529 structureKey = getStructureKey(structureKey);
530
531 return ddmStructurePersistence.fetchByG_C_S(
532 groupId, classNameId, structureKey);
533 }
534
535
558 @Override
559 public DDMStructure fetchStructure(
560 long groupId, long classNameId, String structureKey,
561 boolean includeAncestorStructures)
562 throws PortalException {
563
564 structureKey = getStructureKey(structureKey);
565
566 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
567 groupId, classNameId, structureKey);
568
569 if (structure != null) {
570 return structure;
571 }
572
573 if (!includeAncestorStructures) {
574 return null;
575 }
576
577 for (long ancestorSiteGroupId :
578 PortalUtil.getAncestorSiteGroupIds(groupId)) {
579
580 structure = ddmStructurePersistence.fetchByG_C_S(
581 ancestorSiteGroupId, classNameId, structureKey);
582
583 if (structure != null) {
584 return structure;
585 }
586 }
587
588 return null;
589 }
590
591
595 @Deprecated
596 @Override
597 public List<DDMStructure> getClassStructures(long classNameId) {
598 return ddmStructurePersistence.findByClassNameId(classNameId);
599 }
600
601
605 @Deprecated
606 @Override
607 public List<DDMStructure> getClassStructures(
608 long classNameId, int start, int end) {
609
610 return ddmStructurePersistence.findByClassNameId(
611 classNameId, start, end);
612 }
613
614
622 @Override
623 public List<DDMStructure> getClassStructures(
624 long companyId, long classNameId) {
625
626 return ddmStructurePersistence.findByC_C(companyId, classNameId);
627 }
628
629
650 @Override
651 public List<DDMStructure> getClassStructures(
652 long companyId, long classNameId, int start, int end) {
653
654 return ddmStructurePersistence.findByC_C(
655 companyId, classNameId, start, end);
656 }
657
658
669 @Override
670 public List<DDMStructure> getClassStructures(
671 long companyId, long classNameId,
672 OrderByComparator<DDMStructure> orderByComparator) {
673
674 return ddmStructurePersistence.findByC_C(
675 companyId, classNameId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
676 orderByComparator);
677 }
678
679
683 @Deprecated
684 @Override
685 public List<DDMStructure> getClassStructures(
686 long classNameId, OrderByComparator<DDMStructure> orderByComparator) {
687
688 return ddmStructurePersistence.findByClassNameId(
689 classNameId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
690 orderByComparator);
691 }
692
693
700 @Override
701 public List<DDMStructure> getDLFileEntryTypeStructures(
702 long dlFileEntryTypeId) {
703
704 return dlFileEntryTypePersistence.getDDMStructures(dlFileEntryTypeId);
705 }
706
707 @Override
708 public List<DDMStructure> getJournalFolderStructures(
709 long[] groupIds, long journalFolderId, int restrictionType)
710 throws PortalException {
711
712 if (restrictionType ==
713 JournalFolderConstants.
714 RESTRICTION_TYPE_DDM_STRUCTURES_AND_WORKFLOW) {
715
716 return journalFolderPersistence.getDDMStructures(journalFolderId);
717 }
718
719 List<DDMStructure> structures = null;
720
721 journalFolderId =
722 journalFolderLocalService.getOverridedDDMStructuresFolderId(
723 journalFolderId);
724
725 if (journalFolderId !=
726 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
727
728 structures = journalFolderPersistence.getDDMStructures(
729 journalFolderId);
730 }
731 else {
732 long classNameId = classNameLocalService.getClassNameId(
733 JournalArticle.class);
734
735 structures = ddmStructurePersistence.findByG_C(
736 groupIds, classNameId);
737 }
738
739 return structures;
740 }
741
742
749 @Override
750 public DDMStructure getStructure(long structureId) throws PortalException {
751 return ddmStructurePersistence.findByPrimaryKey(structureId);
752 }
753
754
765 @Override
766 public DDMStructure getStructure(
767 long groupId, long classNameId, String structureKey)
768 throws PortalException {
769
770 structureKey = getStructureKey(structureKey);
771
772 return ddmStructurePersistence.findByG_C_S(
773 groupId, classNameId, structureKey);
774 }
775
776
798 @Override
799 public DDMStructure getStructure(
800 long groupId, long classNameId, String structureKey,
801 boolean includeAncestorStructures)
802 throws PortalException {
803
804 structureKey = getStructureKey(structureKey);
805
806 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
807 groupId, classNameId, structureKey);
808
809 if (structure != null) {
810 return structure;
811 }
812
813 if (!includeAncestorStructures) {
814 throw new NoSuchStructureException(
815 "No DDMStructure exists with the structure key " +
816 structureKey);
817 }
818
819 for (long curGroupId : PortalUtil.getAncestorSiteGroupIds(groupId)) {
820 structure = ddmStructurePersistence.fetchByG_C_S(
821 curGroupId, classNameId, structureKey);
822
823 if (structure != null) {
824 return structure;
825 }
826 }
827
828 throw new NoSuchStructureException(
829 "No DDMStructure exists with the structure key " +
830 structureKey + " in the ancestor groups");
831 }
832
833
841 @Override
842 public List<DDMStructure> getStructure(
843 long groupId, String name, String description) {
844
845 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
846 }
847
848
851 @Deprecated
852 @Override
853 public List<DDMStructure> getStructureEntries() {
854 return getStructures();
855 }
856
857
860 @Deprecated
861 @Override
862 public List<DDMStructure> getStructureEntries(long groupId) {
863 return getStructures(groupId);
864 }
865
866
870 @Deprecated
871 @Override
872 public List<DDMStructure> getStructureEntries(
873 long groupId, int start, int end) {
874
875 return getStructures(groupId, start, end);
876 }
877
878
883 @Override
884 public List<DDMStructure> getStructures() {
885 return ddmStructurePersistence.findAll();
886 }
887
888
894 @Override
895 public List<DDMStructure> getStructures(long groupId) {
896 return ddmStructurePersistence.findByGroupId(groupId);
897 }
898
899
918 @Override
919 public List<DDMStructure> getStructures(long groupId, int start, int end) {
920 return ddmStructurePersistence.findByGroupId(groupId, start, end);
921 }
922
923
931 @Override
932 public List<DDMStructure> getStructures(long groupId, long classNameId) {
933 return ddmStructurePersistence.findByG_C(groupId, classNameId);
934 }
935
936
958 @Override
959 public List<DDMStructure> getStructures(
960 long groupId, long classNameId, int start, int end) {
961
962 return ddmStructurePersistence.findByG_C(
963 groupId, classNameId, start, end);
964 }
965
966
990 @Override
991 public List<DDMStructure> getStructures(
992 long groupId, long classNameId, int start, int end,
993 OrderByComparator<DDMStructure> orderByComparator) {
994
995 return ddmStructurePersistence.findByG_C(
996 groupId, classNameId, start, end, orderByComparator);
997 }
998
999 @Override
1000 public List<DDMStructure> getStructures(
1001 long groupId, String name, String description) {
1002
1003 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
1004 }
1005
1006
1012 @Override
1013 public List<DDMStructure> getStructures(long[] groupIds) {
1014 return ddmStructurePersistence.findByGroupId(groupIds);
1015 }
1016
1017
1026 @Override
1027 public List<DDMStructure> getStructures(long[] groupIds, long classNameId) {
1028 return ddmStructurePersistence.findByG_C(groupIds, classNameId);
1029 }
1030
1031
1053 @Override
1054 public List<DDMStructure> getStructures(
1055 long[] groupIds, long classNameId, int start, int end) {
1056
1057 return ddmStructurePersistence.findByG_C(
1058 groupIds, classNameId, start, end);
1059 }
1060
1061
1067 @Override
1068 public int getStructuresCount(long groupId) {
1069 return ddmStructurePersistence.countByGroupId(groupId);
1070 }
1071
1072
1080 @Override
1081 public int getStructuresCount(long groupId, long classNameId) {
1082 return ddmStructurePersistence.countByG_C(groupId, classNameId);
1083 }
1084
1085
1094 @Override
1095 public int getStructuresCount(long[] groupIds, long classNameId) {
1096 return ddmStructurePersistence.countByG_C(groupIds, classNameId);
1097 }
1098
1099
1127 @Override
1128 public List<DDMStructure> search(
1129 long companyId, long[] groupIds, long[] classNameIds, String keywords,
1130 int start, int end, OrderByComparator<DDMStructure> orderByComparator) {
1131
1132 return ddmStructureFinder.findByKeywords(
1133 companyId, groupIds, classNameIds, keywords, start, end,
1134 orderByComparator);
1135 }
1136
1137
1171 @Override
1172 public List<DDMStructure> search(
1173 long companyId, long[] groupIds, long[] classNameIds, String name,
1174 String description, String storageType, int type, boolean andOperator,
1175 int start, int end, OrderByComparator<DDMStructure> orderByComparator) {
1176
1177 return ddmStructureFinder.findByC_G_C_N_D_S_T(
1178 companyId, groupIds, classNameIds, name, description, storageType,
1179 type, andOperator, start, end, orderByComparator);
1180 }
1181
1182
1194 @Override
1195 public int searchCount(
1196 long companyId, long[] groupIds, long[] classNameIds, String keywords) {
1197
1198 return ddmStructureFinder.countByKeywords(
1199 companyId, groupIds, classNameIds, keywords);
1200 }
1201
1202
1221 @Override
1222 public int searchCount(
1223 long companyId, long[] groupIds, long[] classNameIds, String name,
1224 String description, String storageType, int type, boolean andOperator) {
1225
1226 return ddmStructureFinder.countByC_G_C_N_D_S_T(
1227 companyId, groupIds, classNameIds, name, description, storageType,
1228 type, andOperator);
1229 }
1230
1231
1243 @Override
1244 public DDMStructure updateDefinition(
1245 long structureId, String definition, ServiceContext serviceContext)
1246 throws PortalException {
1247
1248 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
1249 structureId);
1250
1251 return doUpdateStructure(
1252 structure.getParentStructureId(), structure.getNameMap(),
1253 structure.getDescriptionMap(), definition, serviceContext,
1254 structure);
1255 }
1256
1257
1277 @Override
1278 public DDMStructure updateStructure(
1279 long groupId, long parentStructureId, long classNameId,
1280 String structureKey, Map<Locale, String> nameMap,
1281 Map<Locale, String> descriptionMap, String definition,
1282 ServiceContext serviceContext)
1283 throws PortalException {
1284
1285 structureKey = getStructureKey(structureKey);
1286
1287 DDMStructure structure = ddmStructurePersistence.findByG_C_S(
1288 groupId, classNameId, structureKey);
1289
1290 return doUpdateStructure(
1291 parentStructureId, nameMap, descriptionMap, definition,
1292 serviceContext, structure);
1293 }
1294
1295
1311 @Override
1312 public DDMStructure updateStructure(
1313 long structureId, long parentStructureId,
1314 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
1315 String definition, ServiceContext serviceContext)
1316 throws PortalException {
1317
1318 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
1319 structureId);
1320
1321 return doUpdateStructure(
1322 parentStructureId, nameMap, descriptionMap, definition,
1323 serviceContext, structure);
1324 }
1325
1326 protected Set<Long> deleteStructures(List<DDMStructure> structures)
1327 throws PortalException {
1328
1329 Set<Long> deletedStructureIds = new HashSet<Long>();
1330
1331 for (DDMStructure structure : structures) {
1332 if (deletedStructureIds.contains(structure.getStructureId())) {
1333 continue;
1334 }
1335
1336 if (!GroupThreadLocal.isDeleteInProcess()) {
1337 List<DDMStructure> childDDMStructures =
1338 ddmStructurePersistence.findByParentStructureId(
1339 structure.getStructureId());
1340
1341 deletedStructureIds.addAll(
1342 deleteStructures(childDDMStructures));
1343 }
1344
1345 ddmStructureLocalService.deleteStructure(structure);
1346
1347 deletedStructureIds.add(structure.getStructureId());
1348 }
1349
1350 return deletedStructureIds;
1351 }
1352
1353 protected DDMStructure doUpdateStructure(
1354 long parentStructureId, Map<Locale, String> nameMap,
1355 Map<Locale, String> descriptionMap, String definition,
1356 ServiceContext serviceContext, DDMStructure structure)
1357 throws PortalException {
1358
1359 try {
1360 definition = DDMXMLUtil.validateXML(definition);
1361 definition = DDMXMLUtil.formatXML(definition);
1362 }
1363 catch (Exception e) {
1364 throw new StructureDefinitionException();
1365 }
1366
1367 DDMForm parentDDMForm = getParentDDMForm(parentStructureId);
1368
1369 validate(nameMap, parentDDMForm, definition);
1370
1371 structure.setModifiedDate(serviceContext.getModifiedDate(null));
1372 structure.setParentStructureId(parentStructureId);
1373 structure.setNameMap(nameMap);
1374 structure.setDescriptionMap(descriptionMap);
1375 structure.setDefinition(definition);
1376
1377 ddmStructurePersistence.update(structure);
1378
1379 syncStructureTemplatesFields(structure);
1380
1381 Indexer indexer = IndexerRegistryUtil.getIndexer(
1382 structure.getClassName());
1383
1384 if (indexer != null) {
1385 List<Long> ddmStructureIds = getChildrenStructureIds(
1386 structure.getGroupId(), structure.getStructureId());
1387
1388 indexer.reindexDDMStructures(ddmStructureIds);
1389 }
1390
1391 return structure;
1392 }
1393
1394 protected void getChildrenStructureIds(
1395 List<Long> structureIds, long groupId, long parentStructureId)
1396 throws PortalException {
1397
1398 List<DDMStructure> structures = ddmStructurePersistence.findByG_P(
1399 groupId, parentStructureId);
1400
1401 for (DDMStructure structure : structures) {
1402 structureIds.add(structure.getStructureId());
1403
1404 getChildrenStructureIds(
1405 structureIds, structure.getGroupId(),
1406 structure.getStructureId());
1407 }
1408 }
1409
1410 protected List<Long> getChildrenStructureIds(long groupId, long structureId)
1411 throws PortalException {
1412
1413 List<Long> structureIds = new ArrayList<Long>();
1414
1415 getChildrenStructureIds(structureIds, groupId, structureId);
1416
1417 structureIds.add(0, structureId);
1418
1419 return structureIds;
1420 }
1421
1422 protected Set<String> getDDMFormFieldsNames(DDMForm ddmForm) {
1423 Map<String, DDMFormField> ddmFormFieldsMap =
1424 ddmForm.getDDMFormFieldsMap(true);
1425
1426 Set<String> ddmFormFieldsNames = new HashSet<String>(
1427 ddmFormFieldsMap.size());
1428
1429 for (String ddmFormFieldName : ddmFormFieldsMap.keySet()) {
1430 ddmFormFieldsNames.add(StringUtil.toLowerCase(ddmFormFieldName));
1431 }
1432
1433 return ddmFormFieldsNames;
1434 }
1435
1436 protected Set<String> getElementNames(Document document) {
1437 Set<String> elementNames = new HashSet<String>();
1438
1439 XPath xPathSelector = SAXReaderUtil.createXPath("
1440
1441 List<Node> nodes = xPathSelector.selectNodes(document);
1442
1443 for (Node node : nodes) {
1444 Element element = (Element)node;
1445
1446 String name = StringUtil.toLowerCase(
1447 element.attributeValue("name"));
1448
1449 elementNames.add(name);
1450 }
1451
1452 return elementNames;
1453 }
1454
1455 protected DDMForm getParentDDMForm(long parentStructureId) {
1456 DDMStructure parentStructure =
1457 ddmStructurePersistence.fetchByPrimaryKey(parentStructureId);
1458
1459 if (parentStructure == null) {
1460 return null;
1461 }
1462
1463 return parentStructure.getFullHierarchyDDMForm();
1464 }
1465
1466 protected String getStructureKey(String structureKey) {
1467 if (structureKey != null) {
1468 structureKey = structureKey.trim();
1469
1470 return StringUtil.toUpperCase(structureKey);
1471 }
1472
1473 return StringPool.BLANK;
1474 }
1475
1476 protected List<DDMTemplate> getStructureTemplates(
1477 DDMStructure structure, String type) {
1478
1479 long classNameId = classNameLocalService.getClassNameId(
1480 DDMStructure.class);
1481
1482 return ddmTemplateLocalService.getTemplates(
1483 structure.getGroupId(), classNameId, structure.getStructureId(),
1484 type);
1485 }
1486
1487 protected void syncStructureTemplatesFields(final DDMStructure structure) {
1488 TransactionCommitCallbackRegistryUtil.registerCallback(
1489 new Callable<Void>() {
1490
1491 @Override
1492 public Void call() throws Exception {
1493 DDMFormTemplateSynchonizer ddmFormTemplateSynchonizer =
1494 new DDMFormTemplateSynchonizer(structure.getDDMForm());
1495
1496 List<DDMTemplate> templates = getStructureTemplates(
1497 structure, DDMTemplateConstants.TEMPLATE_TYPE_FORM);
1498
1499 ddmFormTemplateSynchonizer.setDDMFormTemplates(templates);
1500
1501 ddmFormTemplateSynchonizer.synchronize();
1502
1503 return null;
1504 }
1505
1506 });
1507 }
1508
1509 protected void validate(DDMForm parentDDMForm, Document childDocument)
1510 throws PortalException {
1511
1512 Set<String> parentElementNames = getDDMFormFieldsNames(parentDDMForm);
1513
1514 for (String childElementName : getElementNames(childDocument)) {
1515 if (parentElementNames.contains(childElementName)) {
1516 throw new StructureDuplicateElementException();
1517 }
1518 }
1519 }
1520
1521 protected void validate(Document document) throws PortalException {
1522 XPath xPathSelector = SAXReaderUtil.createXPath("
1523
1524 List<Node> nodes = xPathSelector.selectNodes(document);
1525
1526 Set<String> elementNames = new HashSet<String>();
1527
1528 for (Node node : nodes) {
1529 Element element = (Element)node;
1530
1531 String name = StringUtil.toLowerCase(
1532 element.attributeValue("name"));
1533
1534 if (name.startsWith(DDMStructureConstants.XSD_NAME_RESERVED)) {
1535 throw new StructureDefinitionException();
1536 }
1537
1538 if (elementNames.contains(name)) {
1539 throw new StructureDuplicateElementException();
1540 }
1541
1542 elementNames.add(name);
1543 }
1544 }
1545
1546 protected void validate(
1547 long groupId, long parentStructureId, long classNameId,
1548 String structureKey, Map<Locale, String> nameMap, String definition)
1549 throws PortalException {
1550
1551 structureKey = getStructureKey(structureKey);
1552
1553 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
1554 groupId, classNameId, structureKey);
1555
1556 if (structure != null) {
1557 StructureDuplicateStructureKeyException sdske =
1558 new StructureDuplicateStructureKeyException();
1559
1560 sdske.setStructureKey(structure.getStructureKey());
1561
1562 throw sdske;
1563 }
1564
1565 DDMForm parentDDMForm = getParentDDMForm(parentStructureId);
1566
1567 validate(nameMap, parentDDMForm, definition);
1568 }
1569
1570 protected void validate(
1571 Map<Locale, String> nameMap, DDMForm parentDDMForm,
1572 String childDefinition)
1573 throws PortalException {
1574
1575 try {
1576 Document document = SAXReaderUtil.read(childDefinition);
1577
1578 Element rootElement = document.getRootElement();
1579
1580 Locale contentDefaultLocale = LocaleUtil.fromLanguageId(
1581 rootElement.attributeValue("default-locale"));
1582
1583 validate(nameMap, contentDefaultLocale);
1584
1585 validate(document);
1586
1587 if (parentDDMForm != null) {
1588 validate(parentDDMForm, document);
1589 }
1590 }
1591 catch (LocaleException le) {
1592 throw le;
1593 }
1594 catch (StructureDuplicateElementException sdee) {
1595 throw sdee;
1596 }
1597 catch (StructureNameException sne) {
1598 throw sne;
1599 }
1600 catch (StructureDefinitionException sde) {
1601 throw sde;
1602 }
1603 catch (Exception e) {
1604 throw new StructureDefinitionException();
1605 }
1606 }
1607
1608 protected void validate(
1609 Map<Locale, String> nameMap, Locale contentDefaultLocale)
1610 throws PortalException {
1611
1612 String name = nameMap.get(contentDefaultLocale);
1613
1614 if (Validator.isNull(name)) {
1615 throw new StructureNameException();
1616 }
1617
1618 Locale[] availableLocales = LanguageUtil.getAvailableLocales();
1619
1620 if (!ArrayUtil.contains(availableLocales, contentDefaultLocale)) {
1621 Long companyId = CompanyThreadLocal.getCompanyId();
1622
1623 LocaleException le = new LocaleException(
1624 LocaleException.TYPE_CONTENT,
1625 "The locale " + contentDefaultLocale +
1626 " is not available in company " + companyId);
1627
1628 le.setSourceAvailableLocales(new Locale[] {contentDefaultLocale});
1629 le.setTargetAvailableLocales(availableLocales);
1630
1631 throw le;
1632 }
1633 }
1634
1635 }