001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.dynamicdatalists.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.language.LanguageUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.ContentTypes;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.kernel.util.OrderByComparator;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.workflow.WorkflowConstants;
029    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
030    import com.liferay.portal.model.CompanyConstants;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portal.service.ServiceContextUtil;
034    import com.liferay.portlet.documentlibrary.NoSuchDirectoryException;
035    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
036    import com.liferay.portlet.documentlibrary.util.DLUtil;
037    import com.liferay.portlet.dynamicdatalists.NoSuchRecordVersionException;
038    import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
039    import com.liferay.portlet.dynamicdatalists.model.DDLRecordConstants;
040    import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
041    import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
042    import com.liferay.portlet.dynamicdatalists.service.base.DDLRecordLocalServiceBaseImpl;
043    import com.liferay.portlet.dynamicdatalists.util.DDLUtil;
044    import com.liferay.portlet.dynamicdatalists.util.comparator.DDLRecordVersionVersionComparator;
045    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
046    import com.liferay.portlet.dynamicdatamapping.storage.Field;
047    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
048    import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
049    
050    import java.io.Serializable;
051    
052    import java.util.Collections;
053    import java.util.Date;
054    import java.util.List;
055    import java.util.Locale;
056    import java.util.Map;
057    
058    /**
059     * @author Marcellus Tavares
060     * @author Eduardo Lundgren
061     */
062    public class DDLRecordLocalServiceImpl
063            extends DDLRecordLocalServiceBaseImpl {
064    
065            public DDLRecord addRecord(
066                            long userId, long groupId, long recordSetId, int displayIndex,
067                            Fields fields, ServiceContext serviceContext)
068                    throws PortalException, SystemException {
069    
070                    // Record
071    
072                    User user = userPersistence.findByPrimaryKey(userId);
073                    Date now = new Date();
074    
075                    DDLRecordSet recordSet = ddlRecordSetPersistence.findByPrimaryKey(
076                            recordSetId);
077    
078                    long recordId = counterLocalService.increment();
079    
080                    DDLRecord record = ddlRecordPersistence.create(recordId);
081    
082                    record.setUuid(serviceContext.getUuid());
083                    record.setGroupId(groupId);
084                    record.setCompanyId(user.getCompanyId());
085                    record.setUserId(user.getUserId());
086                    record.setUserName(user.getFullName());
087                    record.setVersionUserId(user.getUserId());
088                    record.setVersionUserName(user.getFullName());
089                    record.setCreateDate(serviceContext.getCreateDate(now));
090                    record.setModifiedDate(serviceContext.getModifiedDate(now));
091    
092                    long ddmStorageId = StorageEngineUtil.create(
093                            recordSet.getCompanyId(), recordSet.getDDMStructureId(), fields,
094                            serviceContext);
095    
096                    record.setDDMStorageId(ddmStorageId);
097    
098                    record.setRecordSetId(recordSetId);
099                    record.setVersion(DDLRecordConstants.VERSION_DEFAULT);
100                    record.setDisplayIndex(displayIndex);
101    
102                    ddlRecordPersistence.update(record, false);
103    
104                    // Record version
105    
106                    DDLRecordVersion recordVersion = addRecordVersion(
107                            user, record, ddmStorageId, DDLRecordConstants.VERSION_DEFAULT,
108                            displayIndex, WorkflowConstants.STATUS_DRAFT);
109    
110                    // Asset
111    
112                    Locale locale = ServiceContextUtil.getLocale(serviceContext);
113    
114                    updateAsset(
115                            userId, record, recordVersion, serviceContext.getAssetCategoryIds(),
116                            serviceContext.getAssetTagNames(),
117                            locale);
118    
119                    // Workflow
120    
121                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
122                            user.getCompanyId(), groupId, userId, DDLRecord.class.getName(),
123                            recordVersion.getRecordVersionId(), recordVersion, serviceContext);
124    
125                    return record;
126            }
127    
128            public DDLRecord addRecord(
129                            long userId, long groupId, long recordSetId, int displayIndex,
130                            Map<String, Serializable> fieldsMap, ServiceContext serviceContext)
131                    throws PortalException, SystemException {
132    
133                    DDLRecordSet recordSet = ddlRecordSetPersistence.findByPrimaryKey(
134                            recordSetId);
135    
136                    DDMStructure ddmStructure = recordSet.getDDMStructure();
137    
138                    Fields fields = toFields(ddmStructure.getStructureId(), fieldsMap);
139    
140                    return addRecord(
141                            userId, groupId, recordSetId, displayIndex, fields, serviceContext);
142            }
143    
144            public void deleteRecord(DDLRecord record)
145                    throws PortalException, SystemException {
146    
147                    // Record
148    
149                    ddlRecordPersistence.remove(record);
150    
151                    // Record Versions
152    
153                    List<DDLRecordVersion> recordVersions =
154                            ddlRecordVersionPersistence.findByRecordId(record.getRecordId());
155    
156                    for (DDLRecordVersion recordVersion : recordVersions) {
157                            ddlRecordVersionPersistence.remove(recordVersion);
158    
159                            // Dynamic data mapping storage
160    
161                            StorageEngineUtil.deleteByClass(recordVersion.getDDMStorageId());
162    
163                            // Workflow
164    
165                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
166                                    record.getCompanyId(), record.getGroupId(),
167                                    DDLRecord.class.getName(), recordVersion.getPrimaryKey());
168                    }
169    
170                    // Document library
171    
172                    try {
173                            DLStoreUtil.deleteDirectory(
174                                    record.getCompanyId(), CompanyConstants.SYSTEM,
175                                    DDLUtil.getRecordFileUploadPath(record));
176                    }
177                    catch (NoSuchDirectoryException nsde) {
178                            if (_log.isDebugEnabled()) {
179                                    _log.debug(nsde.getMessage());
180                            }
181                    }
182            }
183    
184            public void deleteRecord(long recordId)
185                    throws PortalException, SystemException {
186    
187                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(
188                            recordId);
189    
190                    deleteRecord(record);
191            }
192    
193            public void deleteRecords(long recordSetId)
194                    throws PortalException, SystemException {
195    
196                    List<DDLRecord> records = ddlRecordPersistence.findByRecordSetId(
197                            recordSetId);
198    
199                    for (DDLRecord record : records) {
200                            deleteRecord(record);
201                    }
202            }
203    
204            public DDLRecord fetchRecord(long recordId) throws SystemException {
205                    return ddlRecordPersistence.fetchByPrimaryKey(recordId);
206            }
207    
208            public DDLRecordVersion getLatestRecordVersion(long recordId)
209                    throws PortalException, SystemException {
210    
211                    List<DDLRecordVersion> recordVersions =
212                            ddlRecordVersionPersistence.findByRecordId(recordId);
213    
214                    if (recordVersions.isEmpty()) {
215                            throw new NoSuchRecordVersionException(
216                                    "No record versions found for recordId " + recordId);
217                    }
218    
219                    recordVersions = ListUtil.copy(recordVersions);
220    
221                    Collections.sort(
222                            recordVersions, new DDLRecordVersionVersionComparator());
223    
224                    return recordVersions.get(0);
225            }
226    
227            public DDLRecord getRecord(long recordId)
228                    throws PortalException, SystemException {
229    
230                    return ddlRecordPersistence.findByPrimaryKey(recordId);
231            }
232    
233            public List<DDLRecord> getRecords(long recordSetId)
234                    throws SystemException {
235    
236                    return ddlRecordPersistence.findByRecordSetId(recordSetId);
237            }
238    
239            public List<DDLRecord> getRecords(
240                            long recordSetId, int status, int start, int end,
241                            OrderByComparator orderByComparator)
242                    throws SystemException {
243    
244                    return ddlRecordFinder.findByR_S(
245                            recordSetId, status, start, end, orderByComparator);
246            }
247    
248            public List<DDLRecord> getRecords(long recordSetId, long userId)
249                    throws SystemException {
250    
251                    return ddlRecordPersistence.findByR_U(recordSetId, userId);
252            }
253    
254            public int getRecordsCount(long recordSetId, int status)
255                    throws SystemException {
256    
257                    return ddlRecordFinder.countByR_S(recordSetId, status);
258            }
259    
260            public DDLRecordVersion getRecordVersion(long recordVersionId)
261                    throws PortalException, SystemException {
262    
263                    return ddlRecordVersionPersistence.findByPrimaryKey(recordVersionId);
264            }
265    
266            public DDLRecordVersion getRecordVersion(long recordId, String version)
267                    throws PortalException, SystemException {
268    
269                    return ddlRecordVersionPersistence.findByR_V(recordId, version);
270            }
271    
272            public List<DDLRecordVersion> getRecordVersions(
273                            long recordId, int start, int end,
274                            OrderByComparator orderByComparator)
275                    throws SystemException {
276    
277                    return ddlRecordVersionPersistence.findByRecordId(
278                            recordId, start, end, orderByComparator);
279            }
280    
281            public int getRecordVersionsCount(long recordId)
282                    throws SystemException {
283    
284                    return ddlRecordVersionPersistence.countByRecordId(recordId);
285            }
286    
287            public void revertRecordVersion(
288                            long userId, long recordId, String version,
289                            ServiceContext serviceContext)
290                    throws PortalException, SystemException {
291    
292                    DDLRecordVersion recordVersion = getRecordVersion(recordId, version);
293    
294                    if (!recordVersion.isApproved()) {
295                            return;
296                    }
297    
298                    Fields fields = StorageEngineUtil.getFields(
299                            recordVersion.getDDMStorageId());
300    
301                    updateRecord(
302                            userId, recordId, true, recordVersion.getDisplayIndex(), fields,
303                            false, serviceContext);
304            }
305    
306            public void updateAsset(
307                            long userId, DDLRecord record, DDLRecordVersion recordVersion,
308                            long[] assetCategoryIds, String[] assetTagNames, Locale locale)
309                    throws PortalException, SystemException {
310    
311                    boolean addDraftAssetEntry = false;
312    
313                    if ((recordVersion != null) && !recordVersion.isApproved()) {
314                            String version = recordVersion.getVersion();
315    
316                            if (!version.equals(DDLRecordConstants.VERSION_DEFAULT)) {
317                                    int approvedRecordVersionsCount =
318                                            ddlRecordVersionPersistence.countByR_S(
319                                                    record.getRecordId(),
320                                                    WorkflowConstants.STATUS_APPROVED);
321    
322                                    if (approvedRecordVersionsCount > 0) {
323                                            addDraftAssetEntry = true;
324                                    }
325                            }
326                    }
327    
328                    boolean visible = false;
329    
330                    if ((recordVersion != null) && !recordVersion.isApproved()) {
331                            visible = false;
332                    }
333    
334                    DDLRecordSet recordSet = record.getRecordSet();
335    
336                    String title = LanguageUtil.format(
337                            locale, "new-record-for-list-x", recordSet.getName(locale));
338    
339                    if (addDraftAssetEntry) {
340                            assetEntryLocalService.updateEntry(
341                                    userId, record.getGroupId(), DDLRecordConstants.getClassName(),
342                                    recordVersion.getRecordVersionId(), record.getUuid(), 0,
343                                    assetCategoryIds, assetTagNames, false, null, null, null, null,
344                                    ContentTypes.TEXT_HTML, title, null, StringPool.BLANK, null,
345                                    null, 0, 0, null, false);
346                    }
347                    else {
348                            assetEntryLocalService.updateEntry(
349                                    userId, record.getGroupId(), DDLRecordConstants.getClassName(),
350                                    record.getRecordId(), record.getUuid(), 0, assetCategoryIds,
351                                    assetTagNames, visible, null, null, null, null,
352                                    ContentTypes.TEXT_HTML, title, null, StringPool.BLANK, null,
353                                    null, 0, 0, null, false);
354                    }
355            }
356    
357            public DDLRecord updateRecord(
358                            long userId, long recordId, boolean majorVersion, int displayIndex,
359                            Fields fields, boolean mergeFields, ServiceContext serviceContext)
360                    throws PortalException, SystemException {
361    
362                    // Record
363    
364                    User user = userPersistence.findByPrimaryKey(userId);
365    
366                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(recordId);
367    
368                    record.setModifiedDate(serviceContext.getModifiedDate(null));
369    
370                    ddlRecordPersistence.update(record, false);
371    
372                    // Record version
373    
374                    DDLRecordVersion recordVersion = record.getLatestRecordVersion();
375    
376                    if (recordVersion.isApproved()) {
377                            DDLRecordSet recordSet = record.getRecordSet();
378    
379                            long ddmStorageId = StorageEngineUtil.create(
380                                    recordSet.getCompanyId(), recordSet.getDDMStructureId(), fields,
381                                    serviceContext);
382                            String version = getNextVersion(
383                                    recordVersion.getVersion(), majorVersion,
384                                    serviceContext.getWorkflowAction());
385    
386                            recordVersion = addRecordVersion(
387                                    user, record, ddmStorageId, version, displayIndex,
388                                    WorkflowConstants.STATUS_DRAFT);
389                    }
390                    else {
391                            StorageEngineUtil.update(
392                                    recordVersion.getDDMStorageId(), fields, mergeFields,
393                                    serviceContext);
394    
395                            String version = recordVersion.getVersion();
396    
397                            updateRecordVersion(
398                                    user, recordVersion, version, displayIndex,
399                                    recordVersion.getStatus(), serviceContext);
400                    }
401    
402                    // Workflow
403    
404                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
405                            user.getCompanyId(), record.getGroupId(), userId,
406                            DDLRecord.class.getName(), recordVersion.getRecordVersionId(),
407                            recordVersion, serviceContext);
408    
409                    return record;
410            }
411    
412            public DDLRecord updateRecord(
413                            long userId, long recordId, int displayIndex,
414                            Map<String, Serializable> fieldsMap, boolean mergeFields,
415                            ServiceContext serviceContext)
416                    throws PortalException, SystemException {
417    
418                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(recordId);
419    
420                    DDLRecordSet recordSet = record.getRecordSet();
421    
422                    DDMStructure ddmStructure = recordSet.getDDMStructure();
423    
424                    Fields fields = toFields(ddmStructure.getStructureId(), fieldsMap);
425    
426                    return updateRecord(
427                            userId, recordId, false, displayIndex, fields, mergeFields,
428                            serviceContext);
429            }
430    
431            public DDLRecord updateStatus(
432                            long userId, long recordVersionId, int status,
433                            ServiceContext serviceContext)
434                    throws PortalException, SystemException {
435    
436                    // Record version
437    
438                    User user = userPersistence.findByPrimaryKey(userId);
439    
440                    DDLRecordVersion recordVersion =
441                            ddlRecordVersionPersistence.findByPrimaryKey(recordVersionId);
442    
443                    recordVersion.setStatus(status);
444                    recordVersion.setStatusByUserId(user.getUserId());
445                    recordVersion.setStatusByUserName(user.getFullName());
446                    recordVersion.setStatusDate(new Date());
447    
448                    ddlRecordVersionPersistence.update(recordVersion, false);
449    
450                    // Record
451    
452                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(
453                            recordVersion.getRecordId());
454    
455                    if (status == WorkflowConstants.STATUS_APPROVED) {
456                            if (DLUtil.compareVersions(
457                                            record.getVersion(), recordVersion.getVersion()) <= 0) {
458    
459                                    record.setDDMStorageId(recordVersion.getDDMStorageId());
460                                    record.setVersion(recordVersion.getVersion());
461                                    record.setRecordSetId(recordVersion.getRecordSetId());
462                                    record.setDisplayIndex(recordVersion.getDisplayIndex());
463                                    record.setVersion(recordVersion.getVersion());
464                                    record.setVersionUserId(recordVersion.getUserId());
465                                    record.setVersionUserName(recordVersion.getUserName());
466                                    record.setModifiedDate(recordVersion.getCreateDate());
467    
468                                    ddlRecordPersistence.update(record, false);
469                            }
470                    }
471                    else {
472                            if (record.getVersion().equals(recordVersion.getVersion())) {
473                                    String newVersion = DDLRecordConstants.VERSION_DEFAULT;
474    
475                                    List<DDLRecordVersion> approvedRecordVersions =
476                                            ddlRecordVersionPersistence.findByR_S(
477                                                    record.getRecordId(),
478                                                    WorkflowConstants.STATUS_APPROVED);
479    
480                                    if (!approvedRecordVersions.isEmpty()) {
481                                            newVersion = approvedRecordVersions.get(0).getVersion();
482                                    }
483    
484                                    record.setVersion(newVersion);
485    
486                                    ddlRecordPersistence.update(record, false);
487                            }
488                    }
489    
490                    return record;
491            }
492    
493            protected DDLRecordVersion addRecordVersion(
494                            User user, DDLRecord record, long ddmStorageId, String version,
495                            int displayIndex, int status)
496                    throws SystemException {
497    
498                    long recordVersionId = counterLocalService.increment();
499    
500                    DDLRecordVersion recordVersion = ddlRecordVersionPersistence.create(
501                            recordVersionId);
502    
503                    recordVersion.setGroupId(record.getGroupId());
504                    recordVersion.setCompanyId(record.getCompanyId());
505    
506                    long versionUserId = record.getVersionUserId();
507    
508                    if (versionUserId <= 0) {
509                            versionUserId = record.getUserId();
510                    }
511    
512                    recordVersion.setUserId(versionUserId);
513    
514                    String versionUserName = GetterUtil.getString(
515                            record.getVersionUserName(), record.getUserName());
516    
517                    recordVersion.setUserName(versionUserName);
518    
519                    recordVersion.setCreateDate(record.getModifiedDate());
520                    recordVersion.setDDMStorageId(ddmStorageId);
521                    recordVersion.setRecordSetId(record.getRecordSetId());
522                    recordVersion.setRecordId(record.getRecordId());
523                    recordVersion.setVersion(version);
524                    recordVersion.setDisplayIndex(displayIndex);
525                    recordVersion.setStatus(status);
526                    recordVersion.setStatusByUserId(user.getUserId());
527                    recordVersion.setStatusByUserName(user.getFullName());
528                    recordVersion.setStatusDate(record.getModifiedDate());
529    
530                    ddlRecordVersionPersistence.update(recordVersion, false);
531    
532                    return recordVersion;
533            }
534    
535            protected String getNextVersion(
536                    String version, boolean majorVersion, int workflowAction) {
537    
538                    if (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT) {
539                            majorVersion = false;
540                    }
541    
542                    int[] versionParts = StringUtil.split(version, StringPool.PERIOD, 0);
543    
544                    if (majorVersion) {
545                            versionParts[0]++;
546                            versionParts[1] = 0;
547                    }
548                    else {
549                            versionParts[1]++;
550                    }
551    
552                    return versionParts[0] + StringPool.PERIOD + versionParts[1];
553            }
554    
555            protected Fields toFields(
556                    long ddmStructureId, Map<String, Serializable> fieldsMap) {
557    
558                    Fields fields = new Fields();
559    
560                    for (String name : fieldsMap.keySet()) {
561                            String value = String.valueOf(fieldsMap.get(name));
562    
563                            Field field = new Field(ddmStructureId, name, value);
564    
565                            fields.put(field);
566                    }
567    
568                    return fields;
569            }
570    
571            protected void updateRecordVersion(
572                            User user, DDLRecordVersion recordVersion, String version,
573                            int displayIndex, int status, ServiceContext serviceContext)
574                    throws SystemException {
575    
576                    recordVersion.setVersion(version);
577                    recordVersion.setDisplayIndex(displayIndex);
578                    recordVersion.setStatus(status);
579                    recordVersion.setStatusByUserId(user.getUserId());
580                    recordVersion.setStatusByUserName(user.getFullName());
581                    recordVersion.setStatusDate(serviceContext.getModifiedDate(null));
582    
583                    ddlRecordVersionPersistence.update(recordVersion, false);
584            }
585    
586            private static Log _log = LogFactoryUtil.getLog(
587                    DDLRecordLocalServiceImpl.class);
588    
589    }