001
014
015 package com.liferay.portal.verify;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.json.JSONFactoryUtil;
019 import com.liferay.portal.kernel.json.JSONObject;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.repository.model.FileEntry;
023 import com.liferay.portal.kernel.repository.model.FileVersion;
024 import com.liferay.portal.kernel.repository.model.Folder;
025 import com.liferay.portal.kernel.util.CharPool;
026 import com.liferay.portal.kernel.util.GetterUtil;
027 import com.liferay.portal.kernel.util.MimeTypesUtil;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.Validator;
031 import com.liferay.portal.kernel.xml.Attribute;
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.AuditedModel;
038 import com.liferay.portal.model.BaseModel;
039 import com.liferay.portal.model.CompanyConstants;
040 import com.liferay.portal.model.User;
041 import com.liferay.portal.service.ServiceContext;
042 import com.liferay.portal.service.UserLocalServiceUtil;
043 import com.liferay.portal.util.PortalUtil;
044 import com.liferay.portlet.documentlibrary.NoSuchFolderException;
045 import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
046 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
047 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
048 import com.liferay.portlet.documentlibrary.model.DLSyncConstants;
049 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
050 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
051 import com.liferay.portlet.documentlibrary.service.DLFileEntryMetadataLocalServiceUtil;
052 import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
053 import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
054 import com.liferay.portlet.dynamicdatalists.model.DDLRecordModel;
055 import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
056 import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
057 import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
058 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
059 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureLink;
060 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
061 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
062 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLinkLocalServiceUtil;
063 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
064 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
065 import com.liferay.portlet.dynamicdatamapping.storage.Field;
066 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
067 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
068 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
069 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
070
071 import java.io.File;
072 import java.io.Serializable;
073
074 import java.util.HashMap;
075 import java.util.List;
076 import java.util.Map;
077
078
081 public class VerifyDynamicDataMapping extends VerifyProcess {
082
083 protected FileEntry addFileEntry(
084 long companyId, long userId, long groupId, long folderId,
085 String fileName, String filePath, int status)
086 throws Exception {
087
088 String contentType = MimeTypesUtil.getContentType(fileName);
089
090 String title = fileName;
091
092 int index = title.indexOf(CharPool.PERIOD);
093
094 if (index > 0) {
095 title = title.substring(0, index);
096 }
097
098 try {
099 File file = DLStoreUtil.getFile(
100 companyId, CompanyConstants.SYSTEM, filePath);
101
102 ServiceContext serviceContext = createServiceContext();
103
104 FileEntry fileEntry = DLAppLocalServiceUtil.addFileEntry(
105 userId, groupId, folderId, fileName, contentType, title,
106 StringPool.BLANK, StringPool.BLANK, file, serviceContext);
107
108 updateFileEntryStatus(fileEntry, status, serviceContext);
109
110 return fileEntry;
111 }
112 catch (Exception e) {
113 if (_log.isWarnEnabled()) {
114 _log.warn("Unable to add file entry " + fileName, e);
115 }
116
117 return null;
118 }
119 }
120
121 protected Folder addFolder(
122 long userId, long groupId, long primaryKey, String fieldName)
123 throws Exception {
124
125 Folder ddmFolder = addFolder(
126 userId, groupId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, "DDM",
127 StringPool.BLANK);
128
129 Folder primaryKeyFolder = addFolder(
130 userId, groupId, ddmFolder.getFolderId(),
131 String.valueOf(primaryKey), StringPool.BLANK);
132
133 return addFolder(
134 userId, groupId, primaryKeyFolder.getFolderId(), fieldName,
135 StringPool.BLANK);
136 }
137
138 protected Folder addFolder(
139 long userId, long groupId, long parentFolderId, String name,
140 String description)
141 throws Exception {
142
143 try {
144 return DLAppLocalServiceUtil.getFolder(
145 groupId, parentFolderId, name);
146 }
147 catch (NoSuchFolderException nsfe) {
148 return DLAppLocalServiceUtil.addFolder(
149 userId, groupId, parentFolderId, name, description,
150 createServiceContext());
151 }
152 }
153
154 protected boolean createDefaultMetadataElement(
155 Element dynamicElementElement, String defaultLanguageId) {
156
157 boolean hasDefaultMetadataElement = hasDefaultMetadataElement(
158 dynamicElementElement, defaultLanguageId);
159
160 if (hasDefaultMetadataElement) {
161 return false;
162 }
163
164 Element metadataElement = dynamicElementElement.addElement("meta-data");
165
166 metadataElement.addAttribute("locale", defaultLanguageId);
167
168 Element entryElement = metadataElement.addElement("entry");
169
170 entryElement.addAttribute("name", "label");
171 entryElement.addCDATA(StringPool.BLANK);
172
173 return true;
174 }
175
176 protected ServiceContext createServiceContext() {
177 ServiceContext serviceContext = new ServiceContext();
178
179 serviceContext.setAddGroupPermissions(true);
180 serviceContext.setAddGuestPermissions(true);
181
182 return serviceContext;
183 }
184
185 @Override
186 protected void doVerify() throws Exception {
187 setUpClassNameIds();
188
189 List<DDMStructure> structures =
190 DDMStructureLocalServiceUtil.getStructures();
191
192 for (DDMStructure structure : structures) {
193 verifyStructure(structure);
194
195 updateFileUploadReferences(structure);
196 }
197 }
198
199 protected String getFileUploadPath(BaseModel<?> baseModel)
200 throws Exception {
201
202 StringBundler sb = new StringBundler(7);
203
204 long primaryKey = 0;
205
206 String version = StringPool.BLANK;
207
208 if (baseModel instanceof DDLRecordModel) {
209 DDLRecord ddlRecord = (DDLRecord)baseModel;
210
211 primaryKey = ddlRecord.getPrimaryKey();
212
213 DDLRecordVersion ddlRecordVersion = ddlRecord.getRecordVersion();
214
215 version = ddlRecordVersion.getVersion();
216 }
217 else {
218 DLFileEntryMetadata dlFileEntryMetadata =
219 (DLFileEntryMetadata)baseModel;
220
221 primaryKey = dlFileEntryMetadata.getPrimaryKey();
222
223 DLFileVersion dlFileVersion = dlFileEntryMetadata.getFileVersion();
224
225 version = dlFileVersion.getVersion();
226 }
227
228 sb.append("ddm");
229 sb.append(StringPool.SLASH);
230 sb.append(baseModel.getModelClassName());
231 sb.append(StringPool.SLASH);
232 sb.append(primaryKey);
233 sb.append(StringPool.SLASH);
234 sb.append(version);
235
236 return sb.toString();
237 }
238
239 protected String getJSON(FileEntry fileEntry) {
240 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
241
242 jsonObject.put("groupId", fileEntry.getGroupId());
243 jsonObject.put("uuid", fileEntry.getUuid());
244
245 return jsonObject.toString();
246 }
247
248 protected long getUserId(AuditedModel auditedModel) throws Exception {
249 User user = UserLocalServiceUtil.fetchUser(auditedModel.getUserId());
250
251 if (user != null) {
252 return user.getUserId();
253 }
254
255 User defaultUser = UserLocalServiceUtil.getDefaultUser(
256 auditedModel.getCompanyId());
257
258 if (_log.isWarnEnabled()) {
259 _log.warn(
260 "Using default user " + defaultUser.getUserId() +
261 " for audited model " + auditedModel.getModelClassName() +
262 " with primary key " + auditedModel.getPrimaryKeyObj());
263 }
264
265 return defaultUser.getUserId();
266 }
267
268 protected boolean hasDefaultMetadataElement(
269 Element dynamicElementElement, String defaultLanguageId) {
270
271 List<Element> metadataElements = dynamicElementElement.elements(
272 "meta-data");
273
274 for (Element metadataElement : metadataElements) {
275 String languageId = metadataElement.attributeValue("locale");
276
277 if (languageId.equals(defaultLanguageId)) {
278 return true;
279 }
280 }
281
282 return false;
283 }
284
285 protected boolean hasFileUploadFields(DDMStructure structure)
286 throws Exception {
287
288 Map<String, Map<String, String>> fieldsMap = structure.getFieldsMap();
289
290 for (Map<String, String> field : fieldsMap.values()) {
291 String dataType = field.get(FieldConstants.DATA_TYPE);
292
293 if (dataType.equals("file-upload")) {
294 return true;
295 }
296 }
297
298 return false;
299 }
300
301 protected void setUpClassNameIds() {
302 _ddlRecordSetClassNameId = PortalUtil.getClassNameId(
303 DDLRecordSet.class);
304 _ddmStructureClassNameId = PortalUtil.getClassNameId(
305 DDMStructure.class);
306 _dlFileEntryMetadataClassNameId = PortalUtil.getClassNameId(
307 DLFileEntryMetadata.class);
308 }
309
310 protected void updateDDLFileUploadReferences(long ddlRecordSetId)
311 throws Exception {
312
313 List<DDLRecord> ddlRecords = DDLRecordLocalServiceUtil.getRecords(
314 ddlRecordSetId);
315
316 for (DDLRecord ddlRecord : ddlRecords) {
317 updateFileUploadReferences(
318 ddlRecord.getCompanyId(), ddlRecord.getDDMStorageId(),
319 getUserId(ddlRecord), ddlRecord.getGroupId(), ddlRecord,
320 ddlRecord.getStatus());
321 }
322 }
323
324 protected void updateDLFileUploadReferences(long dlFileEntryMetadataId)
325 throws Exception {
326
327 DLFileEntryMetadata dlFileEntryMetadata =
328 DLFileEntryMetadataLocalServiceUtil.getFileEntryMetadata(
329 dlFileEntryMetadataId);
330
331 FileEntry fileEntry = DLAppLocalServiceUtil.getFileEntry(
332 dlFileEntryMetadata.getFileEntryId());
333
334 FileVersion fileVersion = fileEntry.getFileVersion();
335
336 updateFileUploadReferences(
337 fileEntry.getCompanyId(), dlFileEntryMetadata.getDDMStorageId(),
338 getUserId(fileEntry), fileEntry.getGroupId(), dlFileEntryMetadata,
339 fileVersion.getStatus());
340 }
341
342 protected void updateFieldValues(
343 long storageId, Map<String, String> fieldValues)
344 throws Exception {
345
346 Fields fields = new Fields();
347
348 for (Map.Entry<String, String> entry : fieldValues.entrySet()) {
349 Field field = new Field(
350 storageId, entry.getKey(), entry.getValue());
351
352 fields.put(field);
353 }
354
355 ServiceContext serviceContext = new ServiceContext();
356
357 StorageEngineUtil.update(storageId, fields, true, serviceContext);
358 }
359
360 protected void updateFileEntryStatus(
361 FileEntry fileEntry, int status, ServiceContext serviceContext)
362 throws Exception {
363
364 FileVersion fileVersion = fileEntry.getFileVersion();
365
366 Map<String, Serializable> workflowContext =
367 new HashMap<String, Serializable>();
368
369 workflowContext.put("event", DLSyncConstants.EVENT_ADD);
370
371 DLFileEntryLocalServiceUtil.updateStatus(
372 fileVersion.getUserId(), fileVersion.getFileVersionId(), status,
373 workflowContext, serviceContext);
374 }
375
376 protected void updateFileUploadReferences(DDMStructure structure)
377 throws Exception {
378
379 if (!hasFileUploadFields(structure)) {
380 return;
381 }
382
383 List<DDMStructureLink> structureLinks =
384 DDMStructureLinkLocalServiceUtil.getStructureLinks(
385 structure.getStructureId(), QueryUtil.ALL_POS,
386 QueryUtil.ALL_POS);
387
388 for (DDMStructureLink structureLink : structureLinks) {
389 updateFileUploadReferences(structureLink);
390 }
391
392 updateStructure(structure, updateXSD(structure.getXsd()));
393
394 List<DDMTemplate> templates = DDMTemplateLocalServiceUtil.getTemplates(
395 structure.getGroupId(), _ddmStructureClassNameId,
396 structure.getStructureId(),
397 DDMTemplateConstants.TEMPLATE_TYPE_FORM);
398
399 for (DDMTemplate template : templates) {
400 updateTemplate(template, updateXSD(template.getScript()));
401 }
402 }
403
404 protected void updateFileUploadReferences(DDMStructureLink structureLink)
405 throws Exception {
406
407 long classNameId = structureLink.getClassNameId();
408
409 if (classNameId == _ddlRecordSetClassNameId) {
410 updateDDLFileUploadReferences(structureLink.getClassPK());
411 }
412 else if (classNameId == _dlFileEntryMetadataClassNameId) {
413 updateDLFileUploadReferences(structureLink.getClassPK());
414 }
415 }
416
417 protected void updateFileUploadReferences(
418 long companyId, long storageId, long userId, long groupId,
419 BaseModel<?> baseModel, int status)
420 throws Exception {
421
422 Map<String, String> fieldValues = new HashMap<String, String>();
423
424 Fields fields = StorageEngineUtil.getFields(storageId);
425
426 for (Field field : fields) {
427 String dataType = field.getDataType();
428
429 if (!dataType.equals("file-upload") ||
430 Validator.isNull(field.getValue())) {
431
432 continue;
433 }
434
435 long primaryKey = GetterUtil.getLong(baseModel.getPrimaryKeyObj());
436
437 Folder folder = addFolder(
438 userId, groupId, primaryKey, field.getName());
439
440 String valueString = String.valueOf(field.getValue());
441
442 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
443 valueString);
444
445 String filePath =
446 getFileUploadPath(baseModel) + StringPool.SLASH +
447 field.getName();
448
449 FileEntry fileEntry = addFileEntry(
450 companyId, userId, groupId, folder.getFolderId(),
451 jsonObject.getString("name"), filePath, status);
452
453 if (fileEntry != null) {
454 fieldValues.put(field.getName(), getJSON(fileEntry));
455 }
456 }
457
458 updateFieldValues(storageId, fieldValues);
459 }
460
461 protected void updateStructure(DDMStructure structure, String xsd)
462 throws Exception {
463
464 xsd = DDMXMLUtil.formatXML(xsd);
465
466 structure.setXsd(xsd);
467
468 DDMStructureLocalServiceUtil.updateDDMStructure(structure);
469 }
470
471 protected void updateTemplate(DDMTemplate template, String script)
472 throws Exception {
473
474 script = DDMXMLUtil.formatXML(script);
475
476 template.setScript(script);
477
478 DDMTemplateLocalServiceUtil.updateDDMTemplate(template);
479 }
480
481 protected String updateXSD(String xsd) throws Exception {
482 Document document = SAXReaderUtil.read(xsd);
483
484 Element rootElement = document.getRootElement();
485
486 List<Element> dynamicElementElements = rootElement.elements(
487 "dynamic-element");
488
489 for (Element dynamicElementElement : dynamicElementElements) {
490 updateXSDDynamicElement(dynamicElementElement);
491 }
492
493 return document.asXML();
494 }
495
496 protected void updateXSDDynamicElement(Element element) {
497 String dataType = element.attributeValue("dataType");
498
499 if (Validator.equals(dataType, "file-upload")) {
500 element.addAttribute("dataType", "document-library");
501 element.addAttribute("type", "ddm-documentlibrary");
502 }
503
504 List<Element> dynamicElementElements = element.elements(
505 "dynamic-element");
506
507 for (Element dynamicElementElement : dynamicElementElements) {
508 updateXSDDynamicElement(dynamicElementElement);
509 }
510
511 Attribute attribute = element.attribute("autoGeneratedName");
512
513 if (attribute != null) {
514 element.remove(attribute);
515 }
516 }
517
518 protected void verifyStructure(DDMStructure structure) throws Exception {
519 boolean modified = false;
520
521 String defaultLanguageId = structure.getDefaultLanguageId();
522
523 XPath xPathSelector = SAXReaderUtil.createXPath("
524
525 Document document = structure.getDocument();
526
527 List<Node> nodes = xPathSelector.selectNodes(document);
528
529 for (Node node : nodes) {
530 Element dynamicElementElement = (Element)node;
531
532 updateStructure(structure, updateXSD(structure.getXsd()));
533
534 if (createDefaultMetadataElement(
535 dynamicElementElement, defaultLanguageId)) {
536
537 modified = true;
538 }
539 }
540
541 if (modified) {
542 updateStructure(structure, document.asXML());
543 }
544 }
545
546 private static Log _log = LogFactoryUtil.getLog(
547 VerifyDynamicDataMapping.class);
548
549 private long _ddlRecordSetClassNameId;
550 private long _ddmStructureClassNameId;
551 private long _dlFileEntryMetadataClassNameId;
552
553 }