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