001    /**
002     * Copyright (c) 2000-2011 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.DDLUtil;
043    import com.liferay.portlet.dynamicdatalists.util.comparator.DDLRecordVersionVersionComparator;
044    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
045    import com.liferay.portlet.dynamicdatamapping.storage.Field;
046    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
047    import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
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
062            extends DDLRecordLocalServiceBaseImpl {
063    
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(),
116                            locale);
117    
118                    // Workflow
119    
120                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
121                            user.getCompanyId(), groupId, userId, DDLRecord.class.getName(),
122                            recordVersion.getRecordVersionId(), recordVersion, serviceContext);
123    
124                    return record;
125            }
126    
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            public void deleteRecord(DDLRecord record)
144                    throws PortalException, SystemException {
145    
146                    // Record
147    
148                    ddlRecordPersistence.remove(record);
149    
150                    // Record Versions
151    
152                    List<DDLRecordVersion> recordVersions =
153                            ddlRecordVersionPersistence.findByRecordId(record.getRecordId());
154    
155                    for (DDLRecordVersion recordVersion : recordVersions) {
156                            ddlRecordVersionPersistence.remove(recordVersion);
157    
158                            // Dynamic data mapping storage
159    
160                            StorageEngineUtil.deleteByClass(recordVersion.getDDMStorageId());
161    
162                            // Workflow
163    
164                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
165                                    record.getCompanyId(), record.getGroupId(),
166                                    DDLRecord.class.getName(), recordVersion.getPrimaryKey());
167                    }
168    
169                    // Document library
170    
171                    try {
172                            DLStoreUtil.deleteDirectory(
173                                    record.getCompanyId(), CompanyConstants.SYSTEM,
174                                    DDLUtil.getRecordFileUploadPath(record));
175                    }
176                    catch (NoSuchDirectoryException nsde) {
177                            if (_log.isDebugEnabled()) {
178                                    _log.debug(nsde.getMessage());
179                            }
180                    }
181            }
182    
183            public void deleteRecord(long recordId)
184                    throws PortalException, SystemException {
185    
186                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(recordId);
187    
188                    deleteRecord(record);
189            }
190    
191            public void deleteRecords(long recordSetId)
192                    throws PortalException, SystemException {
193    
194                    List<DDLRecord> records = ddlRecordPersistence.findByRecordSetId(
195                            recordSetId);
196    
197                    for (DDLRecord record : records) {
198                            deleteRecord(record);
199                    }
200            }
201    
202            public DDLRecord fetchRecord(long recordId) throws SystemException {
203                    return ddlRecordPersistence.fetchByPrimaryKey(recordId);
204            }
205    
206            public DDLRecordVersion getLatestRecordVersion(long recordId)
207                    throws PortalException, SystemException {
208    
209                    List<DDLRecordVersion> recordVersions =
210                            ddlRecordVersionPersistence.findByRecordId(recordId);
211    
212                    if (recordVersions.isEmpty()) {
213                            throw new NoSuchRecordVersionException(
214                                    "No record versions found for recordId " + recordId);
215                    }
216    
217                    recordVersions = ListUtil.copy(recordVersions);
218    
219                    Collections.sort(
220                            recordVersions, new DDLRecordVersionVersionComparator());
221    
222                    return recordVersions.get(0);
223            }
224    
225            public DDLRecord getRecord(long recordId)
226                    throws PortalException, SystemException {
227    
228                    return ddlRecordPersistence.findByPrimaryKey(recordId);
229            }
230    
231            public List<DDLRecord> getRecords(long recordSetId)
232                    throws SystemException {
233    
234                    return ddlRecordPersistence.findByRecordSetId(recordSetId);
235            }
236    
237            public List<DDLRecord> getRecords(
238                            long recordSetId, int status, int start, int end,
239                            OrderByComparator orderByComparator)
240                    throws SystemException {
241    
242                    return ddlRecordFinder.findByR_S(
243                            recordSetId, status, start, end, orderByComparator);
244            }
245    
246            public List<DDLRecord> getRecords(long recordSetId, long userId)
247                    throws SystemException {
248    
249                    return ddlRecordPersistence.findByR_U(recordSetId, userId);
250            }
251    
252            public int getRecordsCount(long recordSetId, int status)
253                    throws SystemException {
254    
255                    return ddlRecordFinder.countByR_S(recordSetId, status);
256            }
257    
258            public DDLRecordVersion getRecordVersion(long recordVersionId)
259                    throws PortalException, SystemException {
260    
261                    return ddlRecordVersionPersistence.findByPrimaryKey(recordVersionId);
262            }
263    
264            public DDLRecordVersion getRecordVersion(long recordId, String version)
265                    throws PortalException, SystemException {
266    
267                    return ddlRecordVersionPersistence.findByR_V(recordId, version);
268            }
269    
270            public List<DDLRecordVersion> getRecordVersions(
271                            long recordId, int start, int end,
272                            OrderByComparator orderByComparator)
273                    throws SystemException {
274    
275                    return ddlRecordVersionPersistence.findByRecordId(
276                            recordId, start, end, orderByComparator);
277            }
278    
279            public int getRecordVersionsCount(long recordId)
280                    throws SystemException {
281    
282                    return ddlRecordVersionPersistence.countByRecordId(recordId);
283            }
284    
285            public void revertRecordVersion(
286                            long userId, long recordId, String version,
287                            ServiceContext serviceContext)
288                    throws PortalException, SystemException {
289    
290                    DDLRecordVersion recordVersion = getRecordVersion(recordId, version);
291    
292                    if (!recordVersion.isApproved()) {
293                            return;
294                    }
295    
296                    Fields fields = StorageEngineUtil.getFields(
297                            recordVersion.getDDMStorageId());
298    
299                    updateRecord(
300                            userId, recordId, true, recordVersion.getDisplayIndex(), fields,
301                            false, serviceContext);
302            }
303    
304            public void updateAsset(
305                            long userId, DDLRecord record, DDLRecordVersion recordVersion,
306                            long[] assetCategoryIds, String[] assetTagNames, Locale locale)
307                    throws PortalException, SystemException {
308    
309                    boolean addDraftAssetEntry = false;
310    
311                    if ((recordVersion != null) && !recordVersion.isApproved()) {
312                            String version = recordVersion.getVersion();
313    
314                            if (!version.equals(DDLRecordConstants.VERSION_DEFAULT)) {
315                                    int approvedRecordVersionsCount =
316                                            ddlRecordVersionPersistence.countByR_S(
317                                                    record.getRecordId(),
318                                                    WorkflowConstants.STATUS_APPROVED);
319    
320                                    if (approvedRecordVersionsCount > 0) {
321                                            addDraftAssetEntry = true;
322                                    }
323                            }
324                    }
325    
326                    boolean visible = false;
327    
328                    if ((recordVersion != null) && !recordVersion.isApproved()) {
329                            visible = false;
330                    }
331    
332                    DDLRecordSet recordSet = record.getRecordSet();
333    
334                    String title = LanguageUtil.format(
335                            locale, "new-record-for-list-x", recordSet.getName(locale));
336    
337                    if (addDraftAssetEntry) {
338                            assetEntryLocalService.updateEntry(
339                                    userId, record.getGroupId(), DDLRecordConstants.getClassName(),
340                                    recordVersion.getRecordVersionId(), record.getUuid(), 0,
341                                    assetCategoryIds, assetTagNames, false, null, null, null, null,
342                                    ContentTypes.TEXT_HTML, title, null, StringPool.BLANK, null,
343                                    null, 0, 0, null, false);
344                    }
345                    else {
346                            assetEntryLocalService.updateEntry(
347                                    userId, record.getGroupId(), DDLRecordConstants.getClassName(),
348                                    record.getRecordId(), record.getUuid(), 0, assetCategoryIds,
349                                    assetTagNames, visible, null, null, null, null,
350                                    ContentTypes.TEXT_HTML, title, null, StringPool.BLANK, null,
351                                    null, 0, 0, null, false);
352                    }
353            }
354    
355            public DDLRecord updateRecord(
356                            long userId, long recordId, boolean majorVersion, int displayIndex,
357                            Fields fields, boolean mergeFields, ServiceContext serviceContext)
358                    throws PortalException, SystemException {
359    
360                    // Record
361    
362                    User user = userPersistence.findByPrimaryKey(userId);
363    
364                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(recordId);
365    
366                    record.setModifiedDate(serviceContext.getModifiedDate(null));
367    
368                    ddlRecordPersistence.update(record, false);
369    
370                    // Record version
371    
372                    DDLRecordVersion recordVersion = record.getLatestRecordVersion();
373    
374                    if (recordVersion.isApproved()) {
375                            DDLRecordSet recordSet = record.getRecordSet();
376    
377                            long ddmStorageId = StorageEngineUtil.create(
378                                    recordSet.getCompanyId(), recordSet.getDDMStructureId(), fields,
379                                    serviceContext);
380                            String version = getNextVersion(
381                                    recordVersion.getVersion(), majorVersion,
382                                    serviceContext.getWorkflowAction());
383    
384                            recordVersion = addRecordVersion(
385                                    user, record, ddmStorageId, version, displayIndex,
386                                    WorkflowConstants.STATUS_DRAFT);
387                    }
388                    else {
389                            StorageEngineUtil.update(
390                                    recordVersion.getDDMStorageId(), fields, mergeFields,
391                                    serviceContext);
392    
393                            String version = recordVersion.getVersion();
394    
395                            updateRecordVersion(
396                                    user, recordVersion, version, displayIndex,
397                                    recordVersion.getStatus(), serviceContext);
398                    }
399    
400                    // Workflow
401    
402                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
403                            user.getCompanyId(), record.getGroupId(), userId,
404                            DDLRecord.class.getName(), recordVersion.getRecordVersionId(),
405                            recordVersion, serviceContext);
406    
407                    return record;
408            }
409    
410            public DDLRecord updateRecord(
411                            long userId, long recordId, int displayIndex,
412                            Map<String, Serializable> fieldsMap, boolean mergeFields,
413                            ServiceContext serviceContext)
414                    throws PortalException, SystemException {
415    
416                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(recordId);
417    
418                    DDLRecordSet recordSet = record.getRecordSet();
419    
420                    DDMStructure ddmStructure = recordSet.getDDMStructure();
421    
422                    Fields fields = toFields(ddmStructure.getStructureId(), fieldsMap);
423    
424                    return updateRecord(
425                            userId, recordId, false, displayIndex, fields, mergeFields,
426                            serviceContext);
427            }
428    
429            public DDLRecord updateStatus(
430                            long userId, long recordVersionId, int status,
431                            ServiceContext serviceContext)
432                    throws PortalException, SystemException {
433    
434                    // Record version
435    
436                    User user = userPersistence.findByPrimaryKey(userId);
437    
438                    DDLRecordVersion recordVersion =
439                            ddlRecordVersionPersistence.findByPrimaryKey(recordVersionId);
440    
441                    recordVersion.setStatus(status);
442                    recordVersion.setStatusByUserId(user.getUserId());
443                    recordVersion.setStatusByUserName(user.getFullName());
444                    recordVersion.setStatusDate(new Date());
445    
446                    ddlRecordVersionPersistence.update(recordVersion, false);
447    
448                    // Record
449    
450                    DDLRecord record = ddlRecordPersistence.findByPrimaryKey(
451                            recordVersion.getRecordId());
452    
453                    if (status == WorkflowConstants.STATUS_APPROVED) {
454                            if (DLUtil.compareVersions(
455                                            record.getVersion(), recordVersion.getVersion()) <= 0) {
456    
457                                    record.setDDMStorageId(recordVersion.getDDMStorageId());
458                                    record.setVersion(recordVersion.getVersion());
459                                    record.setRecordSetId(recordVersion.getRecordSetId());
460                                    record.setDisplayIndex(recordVersion.getDisplayIndex());
461                                    record.setVersion(recordVersion.getVersion());
462                                    record.setVersionUserId(recordVersion.getUserId());
463                                    record.setVersionUserName(recordVersion.getUserName());
464                                    record.setModifiedDate(recordVersion.getCreateDate());
465    
466                                    ddlRecordPersistence.update(record, false);
467                            }
468                    }
469                    else {
470                            if (record.getVersion().equals(recordVersion.getVersion())) {
471                                    String newVersion = DDLRecordConstants.VERSION_DEFAULT;
472    
473                                    List<DDLRecordVersion> approvedRecordVersions =
474                                            ddlRecordVersionPersistence.findByR_S(
475                                                    record.getRecordId(),
476                                                    WorkflowConstants.STATUS_APPROVED);
477    
478                                    if (!approvedRecordVersions.isEmpty()) {
479                                            newVersion = approvedRecordVersions.get(0).getVersion();
480                                    }
481    
482                                    record.setVersion(newVersion);
483    
484                                    ddlRecordPersistence.update(record, false);
485                            }
486                    }
487    
488                    return record;
489            }
490    
491            protected DDLRecordVersion addRecordVersion(
492                            User user, DDLRecord record, long ddmStorageId, String version,
493                            int displayIndex, int status)
494                    throws SystemException {
495    
496                    long recordVersionId = counterLocalService.increment();
497    
498                    DDLRecordVersion recordVersion = ddlRecordVersionPersistence.create(
499                            recordVersionId);
500    
501                    recordVersion.setGroupId(record.getGroupId());
502                    recordVersion.setCompanyId(record.getCompanyId());
503    
504                    long versionUserId = record.getVersionUserId();
505    
506                    if (versionUserId <= 0) {
507                            versionUserId = record.getUserId();
508                    }
509    
510                    recordVersion.setUserId(versionUserId);
511    
512                    String versionUserName = GetterUtil.getString(
513                            record.getVersionUserName(), record.getUserName());
514    
515                    recordVersion.setUserName(versionUserName);
516    
517                    recordVersion.setCreateDate(record.getModifiedDate());
518                    recordVersion.setDDMStorageId(ddmStorageId);
519                    recordVersion.setRecordSetId(record.getRecordSetId());
520                    recordVersion.setRecordId(record.getRecordId());
521                    recordVersion.setVersion(version);
522                    recordVersion.setDisplayIndex(displayIndex);
523                    recordVersion.setStatus(status);
524                    recordVersion.setStatusByUserId(user.getUserId());
525                    recordVersion.setStatusByUserName(user.getFullName());
526                    recordVersion.setStatusDate(record.getModifiedDate());
527    
528                    ddlRecordVersionPersistence.update(recordVersion, false);
529    
530                    return recordVersion;
531            }
532    
533            protected String getNextVersion(
534                    String version, boolean majorVersion, int workflowAction) {
535    
536                    if (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT) {
537                            majorVersion = false;
538                    }
539    
540                    int[] versionParts = StringUtil.split(version, StringPool.PERIOD, 0);
541    
542                    if (majorVersion) {
543                            versionParts[0]++;
544                            versionParts[1] = 0;
545                    }
546                    else {
547                            versionParts[1]++;
548                    }
549    
550                    return versionParts[0] + StringPool.PERIOD + versionParts[1];
551            }
552    
553            protected Fields toFields(
554                    long ddmStructureId, Map<String, Serializable> fieldsMap) {
555    
556                    Fields fields = new Fields();
557    
558                    for (String name : fieldsMap.keySet()) {
559                            String value = String.valueOf(fieldsMap.get(name));
560    
561                            Field field = new Field(ddmStructureId, name, value);
562    
563                            fields.put(field);
564                    }
565    
566                    return fields;
567            }
568    
569            protected void updateRecordVersion(
570                            User user, DDLRecordVersion recordVersion, String version,
571                            int displayIndex, int status, ServiceContext serviceContext)
572                    throws SystemException {
573    
574                    recordVersion.setVersion(version);
575                    recordVersion.setDisplayIndex(displayIndex);
576                    recordVersion.setStatus(status);
577                    recordVersion.setStatusByUserId(user.getUserId());
578                    recordVersion.setStatusByUserName(user.getFullName());
579                    recordVersion.setStatusDate(serviceContext.getModifiedDate(null));
580    
581                    ddlRecordVersionPersistence.update(recordVersion, false);
582            }
583    
584            private static Log _log = LogFactoryUtil.getLog(
585                    DDLRecordLocalServiceImpl.class);
586    
587    }