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.dynamicdatamapping.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
022    import com.liferay.portal.kernel.upload.UploadRequest;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.MimeTypesUtil;
025    import com.liferay.portal.kernel.util.OrderByComparator;
026    import com.liferay.portal.kernel.util.StreamUtil;
027    import com.liferay.portal.kernel.util.StringBundler;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.model.BaseModel;
030    import com.liferay.portal.model.CompanyConstants;
031    import com.liferay.portal.service.ServiceContext;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
034    import com.liferay.portlet.documentlibrary.DuplicateFileException;
035    import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
036    import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadataModel;
037    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
038    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
039    import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
040    import com.liferay.portlet.dynamicdatalists.model.DDLRecordModel;
041    import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
042    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
043    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
044    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
045    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
046    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
047    import com.liferay.portlet.dynamicdatamapping.storage.Field;
048    import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
049    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
050    import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
051    import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureIdComparator;
052    import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureModifiedDateComparator;
053    import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateIdComparator;
054    import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateModifiedDateComparator;
055    
056    import java.io.InputStream;
057    import java.io.Serializable;
058    
059    import java.util.Date;
060    import java.util.Set;
061    
062    import javax.servlet.http.HttpServletRequest;
063    import javax.servlet.http.HttpServletResponse;
064    
065    /**
066     * @author Eduardo Lundgren
067     * @author Brian Wing Shun Chan
068     * @author Eduardo Garcia
069     */
070    public class DDMImpl implements DDM {
071    
072            public static final String TYPE_CHECKBOX = "checkbox";
073    
074            public static final String TYPE_DDM_DOCUMENTLIBRARY = "ddm-documentlibrary";
075    
076            public static final String TYPE_DDM_FILEUPLOAD = "ddm-fileupload";
077    
078            public static final String TYPE_RADIO = "radio";
079    
080            public static final String TYPE_SELECT = "select";
081    
082            public Fields getFields(
083                            long ddmStructureId, long ddmTemplateId,
084                            ServiceContext serviceContext)
085                    throws PortalException, SystemException {
086    
087                    return getFields(
088                            ddmStructureId, ddmTemplateId, StringPool.BLANK, serviceContext);
089            }
090    
091            public Fields getFields(
092                            long ddmStructureId, long ddmTemplateId, String fieldNamespace,
093                            ServiceContext serviceContext)
094                    throws PortalException, SystemException {
095    
096                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
097                            ddmStructureId);
098    
099                    try {
100                            DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
101                                    ddmTemplateId);
102    
103                            ddmStructure.setXsd(ddmTemplate.getScript());
104                    }
105                    catch (NoSuchTemplateException nste) {
106                    }
107    
108                    Set<String> fieldNames = ddmStructure.getFieldNames();
109    
110                    Fields fields = new Fields();
111    
112                    for (String fieldName : fieldNames) {
113                            Field field = new Field();
114    
115                            field.setName(fieldName);
116    
117                            String fieldDataType = ddmStructure.getFieldDataType(fieldName);
118                            String fieldType = ddmStructure.getFieldType(fieldName);
119                            Serializable fieldValue = serviceContext.getAttribute(
120                                    fieldNamespace + fieldName);
121    
122                            if (fieldDataType.equals(FieldConstants.DATE)) {
123                                    int fieldValueMonth = GetterUtil.getInteger(
124                                            serviceContext.getAttribute(
125                                                    fieldNamespace + fieldName + "Month"));
126                                    int fieldValueYear = GetterUtil.getInteger(
127                                            serviceContext.getAttribute(
128                                                    fieldNamespace + fieldName + "Year"));
129                                    int fieldValueDay = GetterUtil.getInteger(
130                                            serviceContext.getAttribute(
131                                                    fieldNamespace + fieldName + "Day"));
132    
133                                    Date fieldValueDate = PortalUtil.getDate(
134                                            fieldValueMonth, fieldValueDay, fieldValueYear);
135    
136                                    if (fieldValueDate != null) {
137                                            fieldValue = String.valueOf(fieldValueDate.getTime());
138                                    }
139                            }
140    
141                            if ((fieldValue == null) ||
142                                    fieldDataType.equals(FieldConstants.FILE_UPLOAD)) {
143    
144                                    continue;
145                            }
146    
147                            if (fieldType.equals(DDMImpl.TYPE_RADIO) ||
148                                    fieldType.equals(DDMImpl.TYPE_SELECT)) {
149    
150                                    if (fieldValue instanceof String) {
151                                            fieldValue = new String[] {String.valueOf(fieldValue)};
152                                    }
153    
154                                    fieldValue = JSONFactoryUtil.serialize(fieldValue);
155                            }
156    
157                            Serializable fieldValueSerializable =
158                                    FieldConstants.getSerializable(
159                                            fieldDataType, GetterUtil.getString(fieldValue));
160    
161                            field.setValue(fieldValueSerializable);
162    
163                            fields.put(field);
164                    }
165    
166                    return fields;
167            }
168    
169            public Fields getFields(long ddmStructureId, ServiceContext serviceContext)
170                    throws PortalException, SystemException {
171    
172                    return getFields(ddmStructureId, 0, serviceContext);
173            }
174    
175            public Fields getFields(
176                            long ddmStructureId, String fieldNamespace,
177                            ServiceContext serviceContext)
178                    throws PortalException, SystemException {
179    
180                    return getFields(ddmStructureId, 0, fieldNamespace, serviceContext);
181            }
182    
183            public String getFileUploadPath(BaseModel<?> baseModel) {
184                    StringBundler sb = new StringBundler(7);
185    
186                    try {
187                            long primaryKey = 0;
188    
189                            String version = StringPool.BLANK;
190    
191                            if (baseModel instanceof DDLRecordModel) {
192                                    DDLRecord record = (DDLRecord)baseModel;
193    
194                                    primaryKey = record.getPrimaryKey();
195    
196                                    DDLRecordVersion recordVersion =
197                                            record.getLatestRecordVersion();
198    
199                                    version = recordVersion.getVersion();
200                            }
201                            else if (baseModel instanceof DLFileEntryMetadataModel) {
202                                    DLFileEntryMetadata fileEntryMetadata =
203                                            (DLFileEntryMetadata)baseModel;
204    
205                                    primaryKey = fileEntryMetadata.getPrimaryKey();
206    
207                                    DLFileVersion fileVersion = fileEntryMetadata.getFileVersion();
208    
209                                    version = fileVersion.getVersion();
210                            }
211    
212                            sb.append("ddm");
213                            sb.append(StringPool.SLASH);
214                            sb.append(baseModel.getModelClassName());
215                            sb.append(StringPool.SLASH);
216                            sb.append(primaryKey);
217                            sb.append(StringPool.SLASH);
218                            sb.append(version);
219                    }
220                    catch (Exception e) {
221                    }
222    
223                    return sb.toString();
224            }
225    
226            public OrderByComparator getStructureOrderByComparator(
227                    String orderByCol, String orderByType) {
228    
229                    boolean orderByAsc = false;
230    
231                    if (orderByType.equals("asc")) {
232                            orderByAsc = true;
233                    }
234    
235                    OrderByComparator orderByComparator = null;
236    
237                    if (orderByCol.equals("id")) {
238                            orderByComparator = new StructureIdComparator(orderByAsc);
239                    }
240                    else if (orderByCol.equals("modified-date")) {
241                            orderByComparator = new StructureModifiedDateComparator(orderByAsc);
242                    }
243    
244                    return orderByComparator;
245            }
246    
247            public OrderByComparator getTemplateOrderByComparator(
248                    String orderByCol, String orderByType) {
249    
250                    boolean orderByAsc = false;
251    
252                    if (orderByType.equals("asc")) {
253                            orderByAsc = true;
254                    }
255    
256                    OrderByComparator orderByComparator = null;
257    
258                    if (orderByCol.equals("id")) {
259                            orderByComparator = new TemplateIdComparator(orderByAsc);
260                    }
261                    else if (orderByCol.equals("modified-date")) {
262                            orderByComparator = new TemplateModifiedDateComparator(orderByAsc);
263                    }
264    
265                    return orderByComparator;
266            }
267    
268            public void sendFieldFile(
269                            HttpServletRequest request, HttpServletResponse response,
270                            Field field)
271                    throws Exception {
272    
273                    if (field == null) {
274                            return;
275                    }
276    
277                    DDMStructure structure = field.getDDMStructure();
278    
279                    Serializable fieldValue = field.getValue();
280    
281                    JSONObject fileJSONObject = JSONFactoryUtil.createJSONObject(
282                            String.valueOf(fieldValue));
283    
284                    String fileName = fileJSONObject.getString("name");
285                    String filePath = fileJSONObject.getString("path");
286    
287                    InputStream is = DLStoreUtil.getFileAsStream(
288                            structure.getCompanyId(), CompanyConstants.SYSTEM, filePath);
289                    long contentLength = DLStoreUtil.getFileSize(
290                            structure.getCompanyId(), CompanyConstants.SYSTEM, filePath);
291                    String contentType = MimeTypesUtil.getContentType(fileName);
292    
293                    ServletResponseUtil.sendFile(
294                            request, response, fileName, is, contentLength, contentType);
295            }
296    
297            public String uploadFieldFile(
298                            long structureId, long storageId, BaseModel<?> baseModel,
299                            String fieldName, ServiceContext serviceContext)
300                    throws Exception {
301    
302                    return uploadFieldFile(
303                            structureId, storageId, baseModel, fieldName, StringPool.BLANK,
304                            serviceContext);
305            }
306    
307            public String uploadFieldFile(
308                            long structureId, long storageId, BaseModel<?> baseModel,
309                            String fieldName, String fieldNamespace,
310                            ServiceContext serviceContext)
311                    throws Exception {
312    
313                    HttpServletRequest request = serviceContext.getRequest();
314    
315                    if (!(request instanceof UploadRequest)) {
316                            return StringPool.BLANK;
317                    }
318    
319                    UploadRequest uploadRequest = (UploadRequest)request;
320    
321                    String fileName = uploadRequest.getFileName(fieldNamespace + fieldName);
322    
323                    String fieldValue = StringPool.BLANK;
324    
325                    InputStream inputStream = null;
326    
327                    Fields fields = StorageEngineUtil.getFields(storageId);
328    
329                    try {
330                            inputStream = uploadRequest.getFileAsStream(
331                                    fieldNamespace + fieldName, true);
332    
333                            if (inputStream != null) {
334                                    String filePath = storeFieldFile(
335                                            baseModel, fieldName, inputStream, serviceContext);
336    
337                                    JSONObject recordFileJSONObject =
338                                            JSONFactoryUtil.createJSONObject();
339    
340                                    recordFileJSONObject.put("name", fileName);
341                                    recordFileJSONObject.put("path", filePath);
342                                    recordFileJSONObject.put(
343                                            "className", baseModel.getModelClassName());
344                                    recordFileJSONObject.put(
345                                            "classPK", String.valueOf(baseModel.getPrimaryKeyObj()));
346    
347                                    fieldValue = recordFileJSONObject.toString();
348                            }
349                            else if (fields.contains(fieldName)) {
350                                    return StringPool.BLANK;
351                            }
352    
353                            Field field = new Field(structureId, fieldName, fieldValue);
354    
355                            fields.put(field);
356    
357                            StorageEngineUtil.update(storageId, fields, true, serviceContext);
358                    }
359                    finally {
360                            StreamUtil.cleanUp(inputStream);
361                    }
362    
363                    return fieldValue;
364            }
365    
366            protected String storeFieldFile(
367                            BaseModel<?> baseModel, String fieldName, InputStream inputStream,
368                            ServiceContext serviceContext)
369                    throws Exception {
370    
371                    String dirName = getFileUploadPath(baseModel);
372    
373                    try {
374                            DLStoreUtil.addDirectory(
375                                    serviceContext.getCompanyId(), CompanyConstants.SYSTEM,
376                                    dirName);
377                    }
378                    catch (DuplicateDirectoryException dde) {
379                    }
380    
381                    String fileName = dirName + StringPool.SLASH + fieldName;
382    
383                    try {
384                            DLStoreUtil.addFile(
385                                    serviceContext.getCompanyId(), CompanyConstants.SYSTEM,
386                                    fileName, inputStream);
387                    }
388                    catch (DuplicateFileException dfe) {
389                    }
390    
391                    return fileName;
392            }
393    
394    }