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