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.exception.SystemException;
021 import com.liferay.portal.kernel.language.LanguageUtil;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.search.Indexer;
025 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
026 import com.liferay.portal.kernel.util.ArrayUtil;
027 import com.liferay.portal.kernel.util.CharPool;
028 import com.liferay.portal.kernel.util.GetterUtil;
029 import com.liferay.portal.kernel.util.HtmlUtil;
030 import com.liferay.portal.kernel.util.LocaleUtil;
031 import com.liferay.portal.kernel.util.OrderByComparator;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.portal.kernel.util.Validator;
034 import com.liferay.portal.kernel.xml.Document;
035 import com.liferay.portal.kernel.xml.DocumentException;
036 import com.liferay.portal.kernel.xml.Element;
037 import com.liferay.portal.kernel.xml.Node;
038 import com.liferay.portal.kernel.xml.SAXReaderUtil;
039 import com.liferay.portal.kernel.xml.XPath;
040 import com.liferay.portal.model.Group;
041 import com.liferay.portal.model.ResourceConstants;
042 import com.liferay.portal.model.User;
043 import com.liferay.portal.security.auth.CompanyThreadLocal;
044 import com.liferay.portal.service.ServiceContext;
045 import com.liferay.portal.util.PortalUtil;
046 import com.liferay.portal.util.PropsValues;
047 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
048 import com.liferay.portlet.dynamicdatamapping.RequiredStructureException;
049 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateElementException;
050 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateStructureKeyException;
051 import com.liferay.portlet.dynamicdatamapping.StructureNameException;
052 import com.liferay.portlet.dynamicdatamapping.StructureXsdException;
053 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
054 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
055 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
056 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
057 import com.liferay.portlet.dynamicdatamapping.service.base.DDMStructureLocalServiceBaseImpl;
058 import com.liferay.portlet.dynamicdatamapping.util.DDMTemplateHelperUtil;
059 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
060
061 import java.util.ArrayList;
062 import java.util.Date;
063 import java.util.HashSet;
064 import java.util.List;
065 import java.util.Locale;
066 import java.util.Map;
067 import java.util.Set;
068
069
094 public class DDMStructureLocalServiceImpl
095 extends DDMStructureLocalServiceBaseImpl {
096
097
126 public DDMStructure addStructure(
127 long userId, long groupId, long parentStructureId, long classNameId,
128 String structureKey, Map<Locale, String> nameMap,
129 Map<Locale, String> descriptionMap, String xsd, String storageType,
130 int type, ServiceContext serviceContext)
131 throws PortalException, SystemException {
132
133
134
135 User user = userPersistence.findByPrimaryKey(userId);
136
137 if (Validator.isNull(structureKey)) {
138 structureKey = String.valueOf(counterLocalService.increment());
139 }
140 else {
141 structureKey = structureKey.trim().toUpperCase();
142 }
143
144 try {
145 xsd = DDMXMLUtil.formatXML(xsd);
146 }
147 catch (Exception e) {
148 throw new StructureXsdException();
149 }
150
151 Date now = new Date();
152
153 validate(groupId, classNameId, structureKey, nameMap, xsd);
154
155 long structureId = counterLocalService.increment();
156
157 DDMStructure structure = ddmStructurePersistence.create(structureId);
158
159 structure.setUuid(serviceContext.getUuid());
160 structure.setGroupId(groupId);
161 structure.setCompanyId(user.getCompanyId());
162 structure.setUserId(user.getUserId());
163 structure.setUserName(user.getFullName());
164 structure.setCreateDate(serviceContext.getCreateDate(now));
165 structure.setModifiedDate(serviceContext.getModifiedDate(now));
166 structure.setParentStructureId(parentStructureId);
167 structure.setClassNameId(classNameId);
168 structure.setStructureKey(structureKey);
169 structure.setNameMap(nameMap);
170 structure.setDescriptionMap(descriptionMap);
171 structure.setXsd(xsd);
172 structure.setStorageType(storageType);
173 structure.setType(type);
174
175 ddmStructurePersistence.update(structure);
176
177
178
179 if (serviceContext.isAddGroupPermissions() ||
180 serviceContext.isAddGuestPermissions()) {
181
182 addStructureResources(
183 structure, serviceContext.isAddGroupPermissions(),
184 serviceContext.isAddGuestPermissions());
185 }
186 else {
187 addStructureResources(
188 structure, serviceContext.getGroupPermissions(),
189 serviceContext.getGuestPermissions());
190 }
191
192 return structure;
193 }
194
195
216 public DDMStructure addStructure(
217 long userId, long groupId, long classNameId,
218 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
219 String xsd, ServiceContext serviceContext)
220 throws PortalException, SystemException {
221
222 return addStructure(
223 userId, groupId, DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
224 classNameId, null, nameMap, descriptionMap, xsd,
225 PropsValues.DYNAMIC_DATA_LISTS_STORAGE_TYPE,
226 DDMStructureConstants.TYPE_DEFAULT, serviceContext);
227 }
228
229
258 public DDMStructure addStructure(
259 long userId, long groupId, String parentStructureKey,
260 long classNameId, String structureKey, Map<Locale, String> nameMap,
261 Map<Locale, String> descriptionMap, String xsd, String storageType,
262 int type, ServiceContext serviceContext)
263 throws PortalException, SystemException {
264
265 DDMStructure parentStructure = fetchStructure(
266 groupId, classNameId, parentStructureKey);
267
268 long parentStructureId =
269 DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID;
270
271 if (parentStructure != null) {
272 parentStructureId = parentStructure.getStructureId();
273 }
274
275 return addStructure(
276 userId, groupId, parentStructureId, classNameId, structureKey,
277 nameMap, descriptionMap, xsd, storageType, type, serviceContext);
278 }
279
280
289 public void addStructureResources(
290 DDMStructure structure, boolean addGroupPermissions,
291 boolean addGuestPermissions)
292 throws PortalException, SystemException {
293
294 resourceLocalService.addResources(
295 structure.getCompanyId(), structure.getGroupId(),
296 structure.getUserId(), DDMStructure.class.getName(),
297 structure.getStructureId(), false, addGroupPermissions,
298 addGuestPermissions);
299 }
300
301
310 public void addStructureResources(
311 DDMStructure structure, String[] groupPermissions,
312 String[] guestPermissions)
313 throws PortalException, SystemException {
314
315 resourceLocalService.addModelResources(
316 structure.getCompanyId(), structure.getGroupId(),
317 structure.getUserId(), DDMStructure.class.getName(),
318 structure.getStructureId(), groupPermissions, guestPermissions);
319 }
320
321
338 public DDMStructure copyStructure(
339 long userId, long structureId, Map<Locale, String> nameMap,
340 Map<Locale, String> descriptionMap, ServiceContext serviceContext)
341 throws PortalException, SystemException {
342
343 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
344 structureId);
345
346 return addStructure(
347 userId, structure.getGroupId(), structure.getParentStructureId(),
348 structure.getClassNameId(), null, nameMap, descriptionMap,
349 structure.getXsd(), structure.getStorageType(), structure.getType(),
350 serviceContext);
351 }
352
353 public DDMStructure copyStructure(
354 long userId, long structureId, ServiceContext serviceContext)
355 throws PortalException, SystemException {
356
357 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
358 structureId);
359
360 return addStructure(
361 userId, structure.getGroupId(), structure.getParentStructureId(),
362 structure.getClassNameId(), null, structure.getNameMap(),
363 structure.getDescriptionMap(), structure.getXsd(),
364 structure.getStorageType(), structure.getType(), serviceContext);
365 }
366
367
379 public void deleteStructure(DDMStructure structure)
380 throws PortalException, SystemException {
381
382 if (ddmStructureLinkPersistence.countByStructureId(
383 structure.getStructureId()) > 0) {
384
385 throw new RequiredStructureException(
386 RequiredStructureException.REFERENCED_STRUCTURE_LINK);
387 }
388
389 long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
390
391 if (ddmTemplatePersistence.countByG_C_C(
392 structure.getGroupId(), classNameId,
393 structure.getPrimaryKey()) > 0) {
394
395 throw new RequiredStructureException(
396 RequiredStructureException.REFERENCED_TEMPLATE);
397 }
398
399
400
401 ddmStructurePersistence.remove(structure);
402
403
404
405 resourceLocalService.deleteResource(
406 structure.getCompanyId(), DDMStructure.class.getName(),
407 ResourceConstants.SCOPE_INDIVIDUAL, structure.getStructureId());
408 }
409
410
422 public void deleteStructure(long structureId)
423 throws PortalException, SystemException {
424
425 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
426 structureId);
427
428 deleteStructure(structure);
429 }
430
431
446 public void deleteStructure(
447 long groupId, long classNameId, String structureKey)
448 throws PortalException, SystemException {
449
450 structureKey = structureKey.trim().toUpperCase();
451
452 DDMStructure structure = ddmStructurePersistence.findByG_C_S(
453 groupId, classNameId, structureKey);
454
455 deleteStructure(structure);
456 }
457
458
471 public void deleteStructures(long groupId)
472 throws PortalException, SystemException {
473
474 List<DDMStructure> structures = ddmStructurePersistence.findByGroupId(
475 groupId);
476
477 for (DDMStructure structure : structures) {
478 deleteStructure(structure);
479 }
480 }
481
482
490 public DDMStructure fetchStructure(long structureId)
491 throws SystemException {
492
493 return ddmStructurePersistence.fetchByPrimaryKey(structureId);
494 }
495
496
508 public DDMStructure fetchStructure(
509 long groupId, long classNameId, String structureKey)
510 throws SystemException {
511
512 structureKey = structureKey.trim().toUpperCase();
513
514 return ddmStructurePersistence.fetchByG_C_S(
515 groupId, classNameId, structureKey);
516 }
517
518
539 public DDMStructure fetchStructure(
540 long groupId, long classNameId, String structureKey,
541 boolean includeGlobalStructures)
542 throws PortalException, SystemException {
543
544 structureKey = structureKey.trim().toUpperCase();
545
546 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
547 groupId, classNameId, structureKey);
548
549 if ((structure != null) || !includeGlobalStructures) {
550 return structure;
551 }
552
553 Group group = groupPersistence.findByPrimaryKey(groupId);
554
555 Group companyGroup = groupLocalService.getCompanyGroup(
556 group.getCompanyId());
557
558 return ddmStructurePersistence.fetchByG_C_S(
559 companyGroup.getGroupId(), classNameId, structureKey);
560 }
561
562
571 public DDMStructure fetchStructure(String uuid, long groupId)
572 throws SystemException {
573
574 return ddmStructurePersistence.fetchByUUID_G(uuid, groupId);
575 }
576
577
581 public List<DDMStructure> getClassStructures(long classNameId)
582 throws SystemException {
583
584 return ddmStructurePersistence.findByClassNameId(classNameId);
585 }
586
587
591 public List<DDMStructure> getClassStructures(
592 long classNameId, int start, int end)
593 throws SystemException {
594
595 return ddmStructurePersistence.findByClassNameId(
596 classNameId, start, end);
597 }
598
599
608 public List<DDMStructure> getClassStructures(
609 long companyId, long classNameId)
610 throws SystemException {
611
612 return ddmStructurePersistence.findByC_C(companyId, classNameId);
613 }
614
615
637 public List<DDMStructure> getClassStructures(
638 long companyId, long classNameId, int start, int end)
639 throws SystemException {
640
641 return ddmStructurePersistence.findByC_C(
642 companyId, classNameId, start, end);
643 }
644
645
657 public List<DDMStructure> getClassStructures(
658 long companyId, long classNameId,
659 OrderByComparator orderByComparator)
660 throws SystemException {
661
662 return ddmStructurePersistence.findByC_C(
663 companyId, classNameId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
664 orderByComparator);
665 }
666
667
671 public List<DDMStructure> getClassStructures(
672 long classNameId, OrderByComparator orderByComparator)
673 throws SystemException {
674
675 return ddmStructurePersistence.findByClassNameId(
676 classNameId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
677 orderByComparator);
678 }
679
680
688 public List<DDMStructure> getDLFileEntryTypeStructures(
689 long dlFileEntryTypeId)
690 throws SystemException {
691
692 return dlFileEntryTypePersistence.getDDMStructures(dlFileEntryTypeId);
693 }
694
695
703 public DDMStructure getStructure(long structureId)
704 throws PortalException, SystemException {
705
706 return ddmStructurePersistence.findByPrimaryKey(structureId);
707 }
708
709
721 public DDMStructure getStructure(
722 long groupId, long classNameId, String structureKey)
723 throws PortalException, SystemException {
724
725 structureKey = structureKey.trim().toUpperCase();
726
727 return ddmStructurePersistence.findByG_C_S(
728 groupId, classNameId, structureKey);
729 }
730
731
751 public DDMStructure getStructure(
752 long groupId, long classNameId, String structureKey,
753 boolean includeGlobalStructures)
754 throws PortalException, SystemException {
755
756 structureKey = structureKey.trim().toUpperCase();
757
758 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
759 groupId, classNameId, structureKey);
760
761 if (structure != null) {
762 return structure;
763 }
764
765 if (!includeGlobalStructures) {
766 throw new NoSuchStructureException(
767 "No DDMStructure exists with the structure key " +
768 structureKey);
769 }
770
771 Group group = groupPersistence.findByPrimaryKey(groupId);
772
773 Group companyGroup = groupLocalService.getCompanyGroup(
774 group.getCompanyId());
775
776 return ddmStructurePersistence.findByG_C_S(
777 companyGroup.getGroupId(), classNameId, structureKey);
778 }
779
780
789 public List<DDMStructure> getStructure(
790 long groupId, String name, String description)
791 throws SystemException {
792
793 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
794 }
795
796
799 public List<DDMStructure> getStructureEntries() throws SystemException {
800 return getStructures();
801 }
802
803
806 public List<DDMStructure> getStructureEntries(long groupId)
807 throws SystemException {
808
809 return getStructures(groupId);
810 }
811
812
816 public List<DDMStructure> getStructureEntries(
817 long groupId, int start, int end)
818 throws SystemException {
819
820 return getStructures(groupId, start, end);
821 }
822
823
829 public List<DDMStructure> getStructures() throws SystemException {
830 return ddmStructurePersistence.findAll();
831 }
832
833
840 public List<DDMStructure> getStructures(long groupId)
841 throws SystemException {
842
843 return ddmStructurePersistence.findByGroupId(groupId);
844 }
845
846
867 public List<DDMStructure> getStructures(long groupId, int start, int end)
868 throws SystemException {
869
870 return ddmStructurePersistence.findByGroupId(groupId, start, end);
871 }
872
873
882 public List<DDMStructure> getStructures(long groupId, long classNameId)
883 throws SystemException {
884
885 return ddmStructurePersistence.findByG_C(groupId, classNameId);
886 }
887
888
912 public List<DDMStructure> getStructures(
913 long groupId, long classNameId, int start, int end)
914 throws SystemException {
915
916 return ddmStructurePersistence.findByG_C(
917 groupId, classNameId, start, end);
918 }
919
920
945 public List<DDMStructure> getStructures(
946 long groupId, long classNameId, int start, int end,
947 OrderByComparator orderByComparator)
948 throws SystemException {
949
950 return ddmStructurePersistence.findByG_C(
951 groupId, classNameId, start, end, orderByComparator);
952 }
953
954 public List<DDMStructure> getStructures(
955 long groupId, String name, String description)
956 throws SystemException {
957
958 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
959 }
960
961
968 public List<DDMStructure> getStructures(long[] groupIds)
969 throws SystemException {
970
971 return ddmStructurePersistence.findByGroupId(groupIds);
972 }
973
974
985 public List<DDMStructure> getStructures(long[] groupIds, long classNameId)
986 throws SystemException {
987
988 return ddmStructurePersistence.findByG_C(groupIds, classNameId);
989 }
990
991
998 public int getStructuresCount(long groupId) throws SystemException {
999 return ddmStructurePersistence.countByGroupId(groupId);
1000 }
1001
1002
1011 public int getStructuresCount(long groupId, long classNameId)
1012 throws SystemException {
1013
1014 return ddmStructurePersistence.countByG_C(groupId, classNameId);
1015 }
1016
1017
1046 public List<DDMStructure> search(
1047 long companyId, long[] groupIds, long[] classNameIds,
1048 String keywords, int start, int end,
1049 OrderByComparator orderByComparator)
1050 throws SystemException {
1051
1052 return ddmStructureFinder.findByKeywords(
1053 companyId, groupIds, classNameIds, keywords, start, end,
1054 orderByComparator);
1055 }
1056
1057
1092 public List<DDMStructure> search(
1093 long companyId, long[] groupIds, long[] classNameIds, String name,
1094 String description, String storageType, int type,
1095 boolean andOperator, int start, int end,
1096 OrderByComparator orderByComparator)
1097 throws SystemException {
1098
1099 return ddmStructureFinder.findByC_G_C_N_D_S_T(
1100 companyId, groupIds, classNameIds, name, description, storageType,
1101 type, andOperator, start, end, orderByComparator);
1102 }
1103
1104
1117 public int searchCount(
1118 long companyId, long[] groupIds, long[] classNameIds,
1119 String keywords)
1120 throws SystemException {
1121
1122 return ddmStructureFinder.countByKeywords(
1123 companyId, groupIds, classNameIds, keywords);
1124 }
1125
1126
1146 public int searchCount(
1147 long companyId, long[] groupIds, long[] classNameIds, String name,
1148 String description, String storageType, int type,
1149 boolean andOperator)
1150 throws SystemException {
1151
1152 return ddmStructureFinder.countByC_G_C_N_D_S_T(
1153 companyId, groupIds, classNameIds, name, description, storageType,
1154 type, andOperator);
1155 }
1156
1157
1178 public DDMStructure updateStructure(
1179 long groupId, long parentStructureId, long classNameId,
1180 String structureKey, Map<Locale, String> nameMap,
1181 Map<Locale, String> descriptionMap, String xsd,
1182 ServiceContext serviceContext)
1183 throws PortalException, SystemException {
1184
1185 structureKey = structureKey.trim().toUpperCase();
1186
1187 DDMStructure structure = ddmStructurePersistence.findByG_C_S(
1188 groupId, classNameId, structureKey);
1189
1190 return doUpdateStructure(
1191 parentStructureId, nameMap, descriptionMap, xsd, serviceContext,
1192 structure);
1193 }
1194
1195
1212 public DDMStructure updateStructure(
1213 long structureId, long parentStructureId,
1214 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
1215 String xsd, ServiceContext serviceContext)
1216 throws PortalException, SystemException {
1217
1218 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
1219 structureId);
1220
1221 return doUpdateStructure(
1222 parentStructureId, nameMap, descriptionMap, xsd, serviceContext,
1223 structure);
1224 }
1225
1226
1239 public DDMStructure updateXSD(
1240 long structureId, String xsd, ServiceContext serviceContext)
1241 throws PortalException, SystemException {
1242
1243 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
1244 structureId);
1245
1246 return doUpdateStructure(
1247 structure.getParentStructureId(), structure.getNameMap(),
1248 structure.getDescriptionMap(), xsd, serviceContext, structure);
1249 }
1250
1251
1265 public void updateXSDFieldMetadata(
1266 long structureId, String fieldName, String metadataEntryName,
1267 String metadataEntryValue, ServiceContext serviceContext)
1268 throws PortalException, SystemException {
1269
1270 DDMStructure ddmStructure = fetchDDMStructure(structureId);
1271
1272 if (ddmStructure == null) {
1273 return;
1274 }
1275
1276 String xsd = ddmStructure.getXsd();
1277
1278 try {
1279 Document document = SAXReaderUtil.read(xsd);
1280
1281 Element rootElement = document.getRootElement();
1282
1283 List<Element> dynamicElementElements = rootElement.elements(
1284 "dynamic-element");
1285
1286 for (Element dynamicElementElement : dynamicElementElements) {
1287 String dynamicElementElementFieldName = GetterUtil.getString(
1288 dynamicElementElement.attributeValue("name"));
1289
1290 if (!dynamicElementElementFieldName.equals(fieldName)) {
1291 continue;
1292 }
1293
1294 List<Element> metadataElements = dynamicElementElement.elements(
1295 "meta-data");
1296
1297 for (Element metadataElement : metadataElements) {
1298 List<Element> metadataEntryElements =
1299 metadataElement.elements();
1300
1301 for (Element metadataEntryElement : metadataEntryElements) {
1302 String metadataEntryElementName = GetterUtil.getString(
1303 metadataEntryElement.attributeValue("name"));
1304
1305 if (metadataEntryElementName.equals(
1306 metadataEntryName)) {
1307
1308 metadataEntryElement.setText(metadataEntryValue);
1309 }
1310 }
1311 }
1312 }
1313
1314 updateXSD(structureId, document.asXML(), serviceContext);
1315 }
1316 catch (DocumentException de) {
1317 throw new SystemException(de);
1318 }
1319 }
1320
1321 protected void appendNewStructureRequiredFields(
1322 DDMStructure structure, Document templateDocument) {
1323
1324 String xsd = structure.getXsd();
1325
1326 Document structureDocument = null;
1327
1328 try {
1329 structureDocument = SAXReaderUtil.read(xsd);
1330 }
1331 catch (DocumentException de) {
1332 if (_log.isWarnEnabled()) {
1333 _log.warn(de, de);
1334 }
1335
1336 return;
1337 }
1338
1339 Element templateElement = templateDocument.getRootElement();
1340
1341 XPath structureXPath = SAXReaderUtil.createXPath(
1342 "
1343 "\"true\"]");
1344
1345 List<Node> nodes = structureXPath.selectNodes(structureDocument);
1346
1347 for (Node node : nodes) {
1348 Element element = (Element)node;
1349
1350 String name = element.attributeValue("name");
1351
1352 name = HtmlUtil.escapeXPathAttribute(name);
1353
1354 XPath templateXPath = SAXReaderUtil.createXPath(
1355 "
1356
1357 if (!templateXPath.booleanValueOf(templateDocument)) {
1358 templateElement.add(element.createCopy());
1359 }
1360 }
1361 }
1362
1363 protected DDMStructure doUpdateStructure(
1364 long parentStructureId, Map<Locale, String> nameMap,
1365 Map<Locale, String> descriptionMap, String xsd,
1366 ServiceContext serviceContext, DDMStructure structure)
1367 throws PortalException, SystemException {
1368
1369 try {
1370 xsd = DDMXMLUtil.formatXML(xsd);
1371 }
1372 catch (Exception e) {
1373 throw new StructureXsdException();
1374 }
1375
1376 validate(nameMap, xsd);
1377
1378 structure.setModifiedDate(serviceContext.getModifiedDate(null));
1379 structure.setParentStructureId(parentStructureId);
1380 structure.setNameMap(nameMap);
1381 structure.setDescriptionMap(descriptionMap);
1382 structure.setXsd(xsd);
1383
1384 ddmStructurePersistence.update(structure);
1385
1386 syncStructureTemplatesFields(structure);
1387
1388 Indexer indexer = IndexerRegistryUtil.getIndexer(
1389 structure.getClassName());
1390
1391 if (indexer != null) {
1392 List<Long> ddmStructureIds = getChildrenStructureIds(
1393 structure.getGroupId(), structure.getStructureId());
1394
1395 indexer.reindexDDMStructures(ddmStructureIds);
1396 }
1397
1398 return structure;
1399 }
1400
1401 protected void getChildrenStructureIds(
1402 List<Long> structureIds, long groupId, long structureId)
1403 throws PortalException, SystemException {
1404
1405 List<DDMStructure> structures = ddmStructurePersistence.findByG_P(
1406 groupId, structureId);
1407
1408 for (DDMStructure structure : structures) {
1409 structureIds.add(structure.getStructureId());
1410
1411 getChildrenStructureIds(
1412 structureIds, structure.getGroupId(),
1413 structure.getParentStructureId());
1414 }
1415 }
1416
1417 protected List<Long> getChildrenStructureIds(long groupId, long structureId)
1418 throws PortalException, SystemException {
1419
1420 List<Long> structureIds = new ArrayList<Long>();
1421
1422 getChildrenStructureIds(structureIds, groupId, structureId);
1423
1424 structureIds.add(0, structureId);
1425
1426 return structureIds;
1427 }
1428
1429 protected void syncStructureTemplatesFields(DDMStructure structure)
1430 throws PortalException, SystemException {
1431
1432 long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
1433
1434 List<DDMTemplate> templates = ddmTemplateLocalService.getTemplates(
1435 structure.getGroupId(), classNameId, structure.getStructureId(),
1436 DDMTemplateConstants.TEMPLATE_TYPE_FORM);
1437
1438 for (DDMTemplate template : templates) {
1439 String script = template.getScript();
1440
1441 Document templateDocument = null;
1442
1443 try {
1444 templateDocument = SAXReaderUtil.read(script);
1445 }
1446 catch (DocumentException de) {
1447 if (_log.isWarnEnabled()) {
1448 _log.warn(de, de);
1449 }
1450
1451 continue;
1452 }
1453
1454 Element templateRootElement = templateDocument.getRootElement();
1455
1456 syncStructureTemplatesFields(template, templateRootElement);
1457
1458 appendNewStructureRequiredFields(structure, templateDocument);
1459
1460 try {
1461 script = DDMXMLUtil.formatXML(templateDocument.asXML());
1462 }
1463 catch (Exception e) {
1464 throw new StructureXsdException();
1465 }
1466
1467 template.setScript(script);
1468
1469 ddmTemplatePersistence.update(template);
1470 }
1471 }
1472
1473 protected void syncStructureTemplatesFields(
1474 DDMTemplate template, Element templateElement)
1475 throws PortalException, SystemException {
1476
1477 DDMStructure structure = DDMTemplateHelperUtil.fetchStructure(template);
1478
1479 List<Element> dynamicElementElements = templateElement.elements(
1480 "dynamic-element");
1481
1482 for (Element dynamicElementElement : dynamicElementElements) {
1483 String dataType = dynamicElementElement.attributeValue("dataType");
1484 String fieldName = dynamicElementElement.attributeValue("name");
1485
1486 if (Validator.isNull(dataType)) {
1487 continue;
1488 }
1489
1490 if (!structure.hasField(fieldName)) {
1491 templateElement.remove(dynamicElementElement);
1492
1493 continue;
1494 }
1495
1496 String mode = template.getMode();
1497
1498 if (mode.equals(DDMTemplateConstants.TEMPLATE_MODE_CREATE)) {
1499 boolean fieldRequired = structure.getFieldRequired(fieldName);
1500
1501 List<Element> metadataElements = dynamicElementElement.elements(
1502 "meta-data");
1503
1504 for (Element metadataElement : metadataElements) {
1505 for (Element metadataEntryElement :
1506 metadataElement.elements()) {
1507
1508 String attributeName =
1509 metadataEntryElement.attributeValue("name");
1510
1511 if (fieldRequired && attributeName.equals("required")) {
1512 metadataEntryElement.setText("true");
1513 }
1514 }
1515 }
1516 }
1517
1518 syncStructureTemplatesFields(template, dynamicElementElement);
1519 }
1520 }
1521
1522 protected void validate(List<Element> elements, Set<String> names)
1523 throws PortalException {
1524
1525 for (Element element : elements) {
1526 String elementName = element.getName();
1527
1528 if (elementName.equals("meta-data")) {
1529 continue;
1530 }
1531
1532 String name = element.attributeValue("name", StringPool.BLANK);
1533 String type = element.attributeValue("type", StringPool.BLANK);
1534
1535 if (Validator.isNull(name) ||
1536 name.startsWith(DDMStructureConstants.XSD_NAME_RESERVED)) {
1537
1538 throw new StructureXsdException();
1539 }
1540
1541 char[] charArray = name.toCharArray();
1542
1543 for (int i = 0; i < charArray.length; i++) {
1544 if (!Character.isLetterOrDigit(charArray[i]) &&
1545 (charArray[i] != CharPool.DASH) &&
1546 (charArray[i] != CharPool.UNDERLINE)) {
1547
1548 throw new StructureXsdException();
1549 }
1550 }
1551
1552 String path = name;
1553
1554 Element parentElement = element.getParent();
1555
1556 while (!parentElement.isRootElement()) {
1557 path =
1558 parentElement.attributeValue("name", StringPool.BLANK) +
1559 StringPool.SLASH + path;
1560
1561 parentElement = parentElement.getParent();
1562 }
1563
1564 path = path.toLowerCase();
1565
1566 if (names.contains(path)) {
1567 throw new StructureDuplicateElementException();
1568 }
1569 else {
1570 names.add(path);
1571 }
1572
1573 if (Validator.isNull(type)) {
1574 throw new StructureXsdException();
1575 }
1576
1577 validate(element.elements(), names);
1578 }
1579 }
1580
1581 protected void validate(
1582 long groupId, long classNameId, String structureKey,
1583 Map<Locale, String> nameMap, String xsd)
1584 throws PortalException, SystemException {
1585
1586 structureKey = structureKey.trim().toUpperCase();
1587
1588 DDMStructure structure = ddmStructurePersistence.fetchByG_C_S(
1589 groupId, classNameId, structureKey);
1590
1591 if (structure != null) {
1592 StructureDuplicateStructureKeyException sdske =
1593 new StructureDuplicateStructureKeyException();
1594
1595 sdske.setStructureKey(structure.getStructureKey());
1596
1597 throw sdske;
1598 }
1599
1600 validate(nameMap, xsd);
1601 }
1602
1603 protected void validate(Map<Locale, String> nameMap, String xsd)
1604 throws PortalException {
1605
1606 if (Validator.isNull(xsd)) {
1607 throw new StructureXsdException();
1608 }
1609 else {
1610 try {
1611 List<Element> elements = new ArrayList<Element>();
1612
1613 Document document = SAXReaderUtil.read(xsd);
1614
1615 Element rootElement = document.getRootElement();
1616
1617 List<Element> rootElementElements = rootElement.elements();
1618
1619 if (rootElementElements.isEmpty()) {
1620 throw new StructureXsdException();
1621 }
1622
1623 Locale contentDefaultLocale = LocaleUtil.fromLanguageId(
1624 rootElement.attributeValue("default-locale"));
1625
1626 validateLanguages(nameMap, contentDefaultLocale);
1627
1628 elements.addAll(rootElement.elements());
1629
1630 Set<String> elNames = new HashSet<String>();
1631
1632 validate(elements, elNames);
1633 }
1634 catch (LocaleException le) {
1635 throw le;
1636 }
1637 catch (StructureDuplicateElementException sdee) {
1638 throw sdee;
1639 }
1640 catch (StructureNameException sne) {
1641 throw sne;
1642 }
1643 catch (StructureXsdException sxe) {
1644 throw sxe;
1645 }
1646 catch (Exception e) {
1647 throw new StructureXsdException();
1648 }
1649 }
1650 }
1651
1652 protected void validateLanguages(
1653 Map<Locale, String> nameMap, Locale contentDefaultLocale)
1654 throws PortalException {
1655
1656 String name = nameMap.get(contentDefaultLocale);
1657
1658 if (Validator.isNull(name)) {
1659 throw new StructureNameException();
1660 }
1661
1662 Locale[] availableLocales = LanguageUtil.getAvailableLocales();
1663
1664 if (!ArrayUtil.contains(availableLocales, contentDefaultLocale)) {
1665 Long companyId = CompanyThreadLocal.getCompanyId();
1666
1667 LocaleException le = new LocaleException(
1668 "The locale " + contentDefaultLocale +
1669 " is not available in company " + companyId);
1670
1671 le.setSourceAvailableLocales(new Locale[] {contentDefaultLocale});
1672 le.setTargetAvailableLocales(availableLocales);
1673
1674 throw le;
1675 }
1676 }
1677
1678 private static Log _log = LogFactoryUtil.getLog(
1679 DDMStructureLocalServiceImpl.class);
1680
1681 }