001
014
015 package com.liferay.portlet.dynamicdatamapping.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.CharPool;
022 import com.liferay.portal.kernel.util.LocaleUtil;
023 import com.liferay.portal.kernel.util.OrderByComparator;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.kernel.xml.Document;
027 import com.liferay.portal.kernel.xml.DocumentException;
028 import com.liferay.portal.kernel.xml.Element;
029 import com.liferay.portal.kernel.xml.Node;
030 import com.liferay.portal.kernel.xml.SAXReaderUtil;
031 import com.liferay.portal.kernel.xml.XPath;
032 import com.liferay.portal.model.ResourceConstants;
033 import com.liferay.portal.model.User;
034 import com.liferay.portal.service.ServiceContext;
035 import com.liferay.portlet.dynamicdatamapping.RequiredStructureException;
036 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateElementException;
037 import com.liferay.portlet.dynamicdatamapping.StructureDuplicateStructureKeyException;
038 import com.liferay.portlet.dynamicdatamapping.StructureNameException;
039 import com.liferay.portlet.dynamicdatamapping.StructureXsdException;
040 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
041 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
042 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
043 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
044 import com.liferay.portlet.dynamicdatamapping.service.base.DDMStructureLocalServiceBaseImpl;
045 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
046
047 import java.util.ArrayList;
048 import java.util.Date;
049 import java.util.HashSet;
050 import java.util.Iterator;
051 import java.util.List;
052 import java.util.Locale;
053 import java.util.Map;
054 import java.util.Set;
055
056
061 public class DDMStructureLocalServiceImpl
062 extends DDMStructureLocalServiceBaseImpl {
063
064 public DDMStructure addStructure(
065 long userId, long groupId, long classNameId, String structureKey,
066 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
067 String xsd, String storageType, int type,
068 ServiceContext serviceContext)
069 throws PortalException, SystemException {
070
071
072
073 User user = userPersistence.findByPrimaryKey(userId);
074
075 if (Validator.isNull(structureKey)) {
076 structureKey = String.valueOf(counterLocalService.increment());
077 }
078
079 try {
080 xsd = DDMXMLUtil.formatXML(xsd);
081 }
082 catch (Exception e) {
083 throw new StructureXsdException();
084 }
085
086 Date now = new Date();
087
088 validate(groupId, structureKey, nameMap, xsd);
089
090 long structureId = counterLocalService.increment();
091
092 DDMStructure structure = ddmStructurePersistence.create(structureId);
093
094 structure.setUuid(serviceContext.getUuid());
095 structure.setGroupId(serviceContext.getScopeGroupId());
096 structure.setCompanyId(user.getCompanyId());
097 structure.setUserId(user.getUserId());
098 structure.setUserName(user.getFullName());
099 structure.setCreateDate(serviceContext.getCreateDate(now));
100 structure.setModifiedDate(serviceContext.getModifiedDate(now));
101 structure.setClassNameId(classNameId);
102 structure.setStructureKey(structureKey);
103 structure.setNameMap(nameMap);
104 structure.setDescriptionMap(descriptionMap);
105 structure.setXsd(xsd);
106 structure.setStorageType(storageType);
107 structure.setType(type);
108
109 ddmStructurePersistence.update(structure, false);
110
111
112
113 if (serviceContext.getAddGroupPermissions() ||
114 serviceContext.getAddGuestPermissions()) {
115
116 addStructureResources(
117 structure, serviceContext.getAddGroupPermissions(),
118 serviceContext.getAddGuestPermissions());
119 }
120 else {
121 addStructureResources(
122 structure, serviceContext.getGroupPermissions(),
123 serviceContext.getGuestPermissions());
124 }
125
126 return structure;
127 }
128
129 public void addStructureResources(
130 DDMStructure structure, boolean addGroupPermissions,
131 boolean addGuestPermissions)
132 throws PortalException, SystemException {
133
134 resourceLocalService.addResources(
135 structure.getCompanyId(), structure.getGroupId(),
136 structure.getUserId(), DDMStructure.class.getName(),
137 structure.getStructureId(), false, addGroupPermissions,
138 addGuestPermissions);
139 }
140
141 public void addStructureResources(
142 DDMStructure structure, String[] groupPermissions,
143 String[] guestPermissions)
144 throws PortalException, SystemException {
145
146 resourceLocalService.addModelResources(
147 structure.getCompanyId(), structure.getGroupId(),
148 structure.getUserId(), DDMStructure.class.getName(),
149 structure.getStructureId(), groupPermissions, guestPermissions);
150 }
151
152 public DDMStructure copyStructure(
153 long userId, long structureId, ServiceContext serviceContext)
154 throws PortalException, SystemException {
155
156 DDMStructure structure = getStructure(structureId);
157
158 return addStructure(
159 userId, structure.getGroupId(), structure.getClassNameId(), null,
160 structure.getNameMap(), structure.getDescriptionMap(),
161 structure.getXsd(), structure.getStorageType(),
162 structure.getType(), serviceContext);
163 }
164
165 public void deleteStructure(DDMStructure structure)
166 throws PortalException, SystemException {
167
168 if (ddmStructureLinkPersistence.countByStructureId(
169 structure.getStructureId()) > 0) {
170
171 throw new RequiredStructureException();
172 }
173
174
175
176 ddmStructurePersistence.remove(structure);
177
178
179
180 resourceLocalService.deleteResource(
181 structure.getCompanyId(), DDMStructure.class.getName(),
182 ResourceConstants.SCOPE_INDIVIDUAL, structure.getStructureId());
183 }
184
185 public void deleteStructure(long structureId)
186 throws PortalException, SystemException {
187
188 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
189 structureId);
190
191 deleteStructure(structure);
192 }
193
194 public void deleteStructure(long groupId, String structureKey)
195 throws PortalException, SystemException {
196
197 DDMStructure structure =
198 ddmStructurePersistence.findByG_S(groupId, structureKey);
199
200 deleteStructure(structure);
201 }
202
203 public void deleteStructures(long groupId)
204 throws PortalException, SystemException {
205
206 List<DDMStructure> structures = ddmStructurePersistence.findByGroupId(
207 groupId);
208
209 for (DDMStructure structure : structures) {
210 deleteStructure(structure);
211 }
212 }
213
214 public DDMStructure fetchStructure(long structureId)
215 throws SystemException {
216
217 return ddmStructurePersistence.fetchByPrimaryKey(structureId);
218 }
219
220 public DDMStructure fetchStructure(long groupId, String structureKey)
221 throws SystemException {
222
223 return ddmStructurePersistence.fetchByG_S(groupId, structureKey);
224 }
225
226 public List<DDMStructure> getClassStructures(long classNameId)
227 throws SystemException {
228
229 return ddmStructurePersistence.findByClassNameId(classNameId);
230 }
231
232 public List<DDMStructure> getClassStructures(
233 long classNameId, int start, int end)
234 throws SystemException {
235
236 return ddmStructurePersistence.findByClassNameId(
237 classNameId, start, end);
238 }
239
240 public List<DDMStructure> getDLFileEntryTypeStructures(
241 long dlFileEntryTypeId)
242 throws SystemException {
243
244 return dlFileEntryTypePersistence.getDDMStructures(dlFileEntryTypeId);
245 }
246
247 public DDMStructure getStructure(long structureId)
248 throws PortalException, SystemException {
249
250 return ddmStructurePersistence.findByPrimaryKey(structureId);
251 }
252
253 public DDMStructure getStructure(long groupId, String structureKey)
254 throws PortalException, SystemException {
255
256 return ddmStructurePersistence.findByG_S(groupId, structureKey);
257 }
258
259 public List<DDMStructure> getStructure(
260 long groupId, String name, String description)
261 throws SystemException {
262
263 return ddmStructurePersistence.findByG_N_D(groupId, name, description);
264 }
265
266 public List<DDMStructure> getStructureEntries() throws SystemException {
267 return ddmStructurePersistence.findAll();
268 }
269
270 public List<DDMStructure> getStructureEntries(long groupId)
271 throws SystemException {
272
273 return ddmStructurePersistence.findByGroupId(groupId);
274 }
275
276 public List<DDMStructure> getStructureEntries(
277 long groupId, int start, int end)
278 throws SystemException {
279
280 return ddmStructurePersistence.findByGroupId(groupId, start, end);
281 }
282
283 public int getStructureEntriesCount(long groupId) throws SystemException {
284 return ddmStructurePersistence.countByGroupId(groupId);
285 }
286
287 public List<DDMStructure> search(
288 long companyId, long[] groupIds, long[] classNameIds,
289 String keywords, int start, int end,
290 OrderByComparator orderByComparator)
291 throws SystemException {
292
293 return ddmStructureFinder.findByKeywords(
294 companyId, groupIds, classNameIds, keywords, start, end,
295 orderByComparator);
296 }
297
298 public List<DDMStructure> search(
299 long companyId, long[] groupIds, long[] classNameIds, String name,
300 String description, String storageType, int type,
301 boolean andOperator, int start, int end,
302 OrderByComparator orderByComparator)
303 throws SystemException {
304
305 return ddmStructureFinder.findByC_G_C_N_D_S_T(
306 companyId, groupIds, classNameIds, name, description, storageType,
307 type, andOperator, start, end, orderByComparator);
308 }
309
310 public int searchCount(
311 long companyId, long[] groupIds, long[] classNameIds,
312 String keywords)
313 throws SystemException {
314
315 return ddmStructureFinder.countByKeywords(
316 companyId, groupIds, classNameIds, keywords);
317 }
318
319 public int searchCount(
320 long companyId, long[] groupIds, long[] classNameIds, String name,
321 String description, String storageType, int type,
322 boolean andOperator)
323 throws SystemException {
324
325 return ddmStructureFinder.countByC_G_C_N_D_S_T(
326 companyId, groupIds, classNameIds, name, description, storageType,
327 type, andOperator);
328 }
329
330 public DDMStructure updateStructure(
331 long structureId, Map<Locale, String> nameMap,
332 Map<Locale, String> descriptionMap, String xsd,
333 ServiceContext serviceContext)
334 throws PortalException, SystemException {
335
336 DDMStructure structure = ddmStructurePersistence.findByPrimaryKey(
337 structureId);
338
339 return doUpdateStructure(
340 nameMap, descriptionMap, xsd, serviceContext, structure);
341 }
342
343 public DDMStructure updateStructure(
344 long groupId, String structureKey, Map<Locale, String> nameMap,
345 Map<Locale, String> descriptionMap, String xsd,
346 ServiceContext serviceContext)
347 throws PortalException, SystemException {
348
349 DDMStructure structure = ddmStructurePersistence.findByG_S(
350 groupId, structureKey);
351
352 return doUpdateStructure(
353 nameMap, descriptionMap, xsd, serviceContext, structure);
354 }
355
356 protected void appendNewStructureRequiredFields(
357 DDMStructure structure, Document templateDocument) {
358
359 String xsd = structure.getXsd();
360
361 Document structureDocument = null;
362
363 try {
364 structureDocument = SAXReaderUtil.read(xsd);
365 }
366 catch (DocumentException de) {
367 if (_log.isWarnEnabled()) {
368 _log.warn(de, de);
369 }
370
371 return;
372 }
373
374 Element templateElement = templateDocument.getRootElement();
375
376 XPath structureXPath = SAXReaderUtil.createXPath(
377 "
378 "\"true\"]");
379
380 List<Node> nodes = structureXPath.selectNodes(structureDocument);
381
382 Iterator<Node> itr = nodes.iterator();
383
384 while (itr.hasNext()) {
385 Element element = (Element)itr.next();
386
387 String name = element.attributeValue("name");
388
389 XPath templateXPath = SAXReaderUtil.createXPath(
390 "
391
392 if (!templateXPath.booleanValueOf(templateDocument)) {
393 templateElement.add(element.createCopy());
394 }
395 }
396 }
397
398 protected DDMStructure doUpdateStructure(
399 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
400 String xsd, ServiceContext serviceContext, DDMStructure structure)
401 throws PortalException, SystemException {
402
403 try {
404 xsd = DDMXMLUtil.formatXML(xsd);
405 }
406 catch (Exception e) {
407 throw new StructureXsdException();
408 }
409
410 validate(nameMap, xsd);
411
412 structure.setModifiedDate(serviceContext.getModifiedDate(null));
413 structure.setNameMap(nameMap);
414 structure.setDescriptionMap(descriptionMap);
415 structure.setXsd(xsd);
416
417 ddmStructurePersistence.update(structure, false);
418
419 syncStructureTemplatesFields(structure);
420
421 return structure;
422 }
423
424 protected void syncStructureTemplatesFields(DDMStructure structure)
425 throws PortalException, SystemException {
426
427 List<DDMTemplate> templates = ddmTemplateLocalService.getTemplates(
428 structure.getStructureId(),
429 DDMTemplateConstants.TEMPLATE_TYPE_DETAIL);
430
431 for (DDMTemplate template : templates) {
432 String script = template.getScript();
433
434 Document templateDocument = null;
435
436 try {
437 templateDocument = SAXReaderUtil.read(script);
438 }
439 catch (DocumentException de) {
440 if (_log.isWarnEnabled()) {
441 _log.warn(de, de);
442 }
443
444 continue;
445 }
446
447 Element templateRootElement = templateDocument.getRootElement();
448
449 syncStructureTemplatesFields(template, templateRootElement);
450
451 appendNewStructureRequiredFields(structure, templateDocument);
452
453 try {
454 script = DDMXMLUtil.formatXML(templateDocument.asXML());
455 }
456 catch (Exception e) {
457 throw new StructureXsdException();
458 }
459
460 template.setScript(script);
461
462 ddmTemplatePersistence.update(template, false);
463 }
464 }
465
466 protected void syncStructureTemplatesFields(
467 DDMTemplate template, Element templateElement)
468 throws PortalException, SystemException {
469
470 DDMStructure structure = template.getStructure();
471
472 List<Element> dynamicElementElements = templateElement.elements(
473 "dynamic-element");
474
475 for (Element dynamicElementElement : dynamicElementElements) {
476 String dataType = dynamicElementElement.attributeValue("dataType");
477 String fieldName = dynamicElementElement.attributeValue("name");
478
479 if (Validator.isNull(dataType)) {
480 continue;
481 }
482
483 if (!structure.hasField(fieldName)) {
484 templateElement.remove(dynamicElementElement);
485
486 continue;
487 }
488
489 String mode = template.getMode();
490
491 if (mode.equals(DDMTemplateConstants.TEMPLATE_MODE_CREATE)) {
492 boolean fieldRequired = structure.getFieldRequired(fieldName);
493
494 List<Element> metadataElements = dynamicElementElement.elements(
495 "meta-data");
496
497 for (Element metadataElement : metadataElements) {
498 for (Element metadataEntryElement :
499 metadataElement.elements()) {
500
501 String attributeName =
502 metadataEntryElement.attributeValue("name");
503
504 if (fieldRequired &&
505 attributeName.equals("required")) {
506
507 metadataEntryElement.setText("true");
508 }
509 }
510 }
511 }
512
513 syncStructureTemplatesFields(template, dynamicElementElement);
514 }
515 }
516
517 protected void validate(List<Element> elements, Set<String> names)
518 throws PortalException {
519
520 for (Element element : elements) {
521 String elementName = element.getName();
522
523 if (elementName.equals("meta-data")) {
524 continue;
525 }
526
527 String name = element.attributeValue("name", StringPool.BLANK);
528 String type = element.attributeValue("type", StringPool.BLANK);
529
530 if (Validator.isNull(name) ||
531 name.startsWith(DDMStructureConstants.XSD_NAME_RESERVED)) {
532
533 throw new StructureXsdException();
534 }
535
536 char[] charArray = name.toCharArray();
537
538 for (int i = 0; i < charArray.length; i++) {
539 if (!Character.isLetterOrDigit(charArray[i]) &&
540 (charArray[i] != CharPool.DASH) &&
541 (charArray[i] != CharPool.UNDERLINE)) {
542
543 throw new StructureXsdException();
544 }
545 }
546
547 String path = name;
548
549 Element parentElement = element.getParent();
550
551 while (!parentElement.isRootElement()) {
552 path =
553 parentElement.attributeValue("name", StringPool.BLANK) +
554 StringPool.SLASH + path;
555
556 parentElement = parentElement.getParent();
557 }
558
559 path = path.toLowerCase();
560
561 if (names.contains(path)) {
562 throw new StructureDuplicateElementException();
563 }
564 else {
565 names.add(path);
566 }
567
568 if (Validator.isNull(type)) {
569 throw new StructureXsdException();
570 }
571
572 validate(element.elements(), names);
573 }
574 }
575
576 protected void validate(
577 long groupId, String structureKey, Map<Locale, String> nameMap,
578 String xsd)
579 throws PortalException, SystemException {
580
581 DDMStructure structure = ddmStructurePersistence.fetchByG_S(
582 groupId, structureKey);
583
584 if (structure != null) {
585 throw new StructureDuplicateStructureKeyException();
586 }
587
588 validate(nameMap, xsd);
589 }
590
591 protected void validate(Map<Locale, String> nameMap, String xsd)
592 throws PortalException {
593
594 validateName(nameMap);
595
596 if (Validator.isNull(xsd)) {
597 throw new StructureXsdException();
598 }
599 else {
600 try {
601 List<Element> elements = new ArrayList<Element>();
602
603 Document document = SAXReaderUtil.read(xsd);
604
605 Element rootElement = document.getRootElement();
606
607 if (rootElement.elements().isEmpty()) {
608 throw new StructureXsdException();
609 }
610
611 elements.addAll(rootElement.elements());
612
613 Set<String> elNames = new HashSet<String>();
614
615 validate(elements, elNames);
616 }
617 catch (StructureDuplicateElementException fdsee) {
618 throw fdsee;
619 }
620 catch (StructureXsdException sxe) {
621 throw sxe;
622 }
623 catch (Exception e) {
624 throw new StructureXsdException();
625 }
626 }
627 }
628
629 protected void validateName(Map<Locale, String> nameMap)
630 throws PortalException {
631
632 String name = nameMap.get(LocaleUtil.getDefault());
633
634 if (Validator.isNull(name)) {
635 throw new StructureNameException();
636 }
637 }
638
639 private static Log _log = LogFactoryUtil.getLog(
640 DDMStructureLocalServiceImpl.class);
641
642 }