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