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