001
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.FileUtil;
024 import com.liferay.portal.kernel.util.GetterUtil;
025 import com.liferay.portal.kernel.util.ListUtil;
026 import com.liferay.portal.kernel.util.LocaleUtil;
027 import com.liferay.portal.kernel.util.MimeTypesUtil;
028 import com.liferay.portal.kernel.util.OrderByComparator;
029 import com.liferay.portal.kernel.util.StreamUtil;
030 import com.liferay.portal.kernel.util.StringBundler;
031 import com.liferay.portal.kernel.util.StringPool;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.util.UnicodeFormatter;
034 import com.liferay.portal.kernel.util.Validator;
035 import com.liferay.portal.kernel.util.WebKeys;
036 import com.liferay.portal.model.BaseModel;
037 import com.liferay.portal.model.CompanyConstants;
038 import com.liferay.portal.service.ServiceContext;
039 import com.liferay.portal.theme.ThemeDisplay;
040 import com.liferay.portal.util.PortalUtil;
041 import com.liferay.portal.util.PropsValues;
042 import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
043 import com.liferay.portlet.documentlibrary.DuplicateFileException;
044 import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
045 import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadataModel;
046 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
047 import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
048 import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
049 import com.liferay.portlet.dynamicdatalists.model.DDLRecordModel;
050 import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
051 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
052 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
053 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
054 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
055 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
056 import com.liferay.portlet.dynamicdatamapping.storage.Field;
057 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
058 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
059 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
060 import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureIdComparator;
061 import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureModifiedDateComparator;
062 import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateIdComparator;
063 import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateModifiedDateComparator;
064
065 import java.io.File;
066 import java.io.IOException;
067 import java.io.InputStream;
068 import java.io.Serializable;
069
070 import java.util.ArrayList;
071 import java.util.Date;
072 import java.util.Iterator;
073 import java.util.List;
074 import java.util.Locale;
075 import java.util.Set;
076
077 import javax.servlet.http.HttpServletRequest;
078 import javax.servlet.http.HttpServletResponse;
079
080
086 public class DDMImpl implements DDM {
087
088 public static final String FIELDS_DISPLAY_NAME = "_fieldsDisplay";
089
090 public static final String INSTANCE_SEPARATOR = "_INSTANCE_";
091
092 public static final String TYPE_CHECKBOX = "checkbox";
093
094 public static final String TYPE_DDM_DOCUMENTLIBRARY = "ddm-documentlibrary";
095
096 public static final String TYPE_DDM_FILEUPLOAD = "ddm-fileupload";
097
098 public static final String TYPE_DDM_LINK_TO_PAGE = "ddm-link-to-page";
099
100 public static final String TYPE_RADIO = "radio";
101
102 public static final String TYPE_SELECT = "select";
103
104 public Fields getFields(
105 long ddmStructureId, long ddmTemplateId,
106 ServiceContext serviceContext)
107 throws PortalException, SystemException {
108
109 return getFields(
110 ddmStructureId, ddmTemplateId, StringPool.BLANK, serviceContext);
111 }
112
113 public Fields getFields(
114 long ddmStructureId, long ddmTemplateId, String fieldNamespace,
115 ServiceContext serviceContext)
116 throws PortalException, SystemException {
117
118 DDMStructure ddmStructure = getDDMStructure(
119 ddmStructureId, ddmTemplateId);
120
121 Set<String> fieldNames = ddmStructure.getFieldNames();
122
123 Fields fields = new Fields();
124
125 for (String fieldName : fieldNames) {
126 List<Serializable> fieldValues = getFieldValues(
127 ddmStructure, fieldName, fieldNamespace, serviceContext);
128
129 if ((fieldValues == null) || fieldValues.isEmpty()) {
130 continue;
131 }
132
133 Field field = new Field();
134
135 field.setDDMStructureId(ddmStructureId);
136
137 String languageId = GetterUtil.getString(
138 serviceContext.getAttribute("languageId"),
139 serviceContext.getLanguageId());
140
141 Locale locale = LocaleUtil.fromLanguageId(languageId);
142
143 String defaultLanguageId = GetterUtil.getString(
144 serviceContext.getAttribute("defaultLanguageId"));
145
146 Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
147
148 if (ddmStructure.isFieldPrivate(fieldName)) {
149 locale = LocaleUtil.getDefault();
150
151 defaultLocale = LocaleUtil.getDefault();
152 }
153
154 field.setDefaultLocale(defaultLocale);
155
156 field.setName(fieldName);
157 field.setValues(locale, fieldValues);
158
159 fields.put(field);
160 }
161
162 return fields;
163 }
164
165 public Fields getFields(long ddmStructureId, ServiceContext serviceContext)
166 throws PortalException, SystemException {
167
168 return getFields(ddmStructureId, 0, serviceContext);
169 }
170
171 public Fields getFields(
172 long ddmStructureId, String fieldNamespace,
173 ServiceContext serviceContext)
174 throws PortalException, SystemException {
175
176 return getFields(ddmStructureId, 0, fieldNamespace, serviceContext);
177 }
178
179 public String[] getFieldsDisplayValues(Field fieldsDisplayField)
180 throws Exception {
181
182 DDMStructure ddmStructure = fieldsDisplayField.getDDMStructure();
183
184 List<String> fieldsDisplayValues = new ArrayList<String>();
185
186 String[] values = StringUtil.split(
187 (String)fieldsDisplayField.getValue());
188
189 for (String value : values) {
190 String fieldName = StringUtil.extractFirst(
191 value, DDMImpl.INSTANCE_SEPARATOR);
192
193 if (ddmStructure.hasField(fieldName)) {
194 fieldsDisplayValues.add(fieldName);
195 }
196 }
197
198 return fieldsDisplayValues.toArray(
199 new String[fieldsDisplayValues.size()]);
200 }
201
202 public String getFileUploadPath(BaseModel<?> baseModel) {
203 StringBundler sb = new StringBundler(7);
204
205 try {
206 long primaryKey = 0;
207
208 String version = StringPool.BLANK;
209
210 if (baseModel instanceof DDLRecordModel) {
211 DDLRecord record = (DDLRecord)baseModel;
212
213 primaryKey = record.getPrimaryKey();
214
215 DDLRecordVersion recordVersion =
216 record.getLatestRecordVersion();
217
218 version = recordVersion.getVersion();
219 }
220 else if (baseModel instanceof DLFileEntryMetadataModel) {
221 DLFileEntryMetadata fileEntryMetadata =
222 (DLFileEntryMetadata)baseModel;
223
224 primaryKey = fileEntryMetadata.getPrimaryKey();
225
226 DLFileVersion fileVersion = fileEntryMetadata.getFileVersion();
227
228 version = fileVersion.getVersion();
229 }
230
231 sb.append("ddm");
232 sb.append(StringPool.SLASH);
233 sb.append(baseModel.getModelClassName());
234 sb.append(StringPool.SLASH);
235 sb.append(primaryKey);
236 sb.append(StringPool.SLASH);
237 sb.append(version);
238 }
239 catch (Exception e) {
240 }
241
242 return sb.toString();
243 }
244
245 public OrderByComparator getStructureOrderByComparator(
246 String orderByCol, String orderByType) {
247
248 boolean orderByAsc = false;
249
250 if (orderByType.equals("asc")) {
251 orderByAsc = true;
252 }
253
254 OrderByComparator orderByComparator = null;
255
256 if (orderByCol.equals("id")) {
257 orderByComparator = new StructureIdComparator(orderByAsc);
258 }
259 else if (orderByCol.equals("modified-date")) {
260 orderByComparator = new StructureModifiedDateComparator(orderByAsc);
261 }
262
263 return orderByComparator;
264 }
265
266 public OrderByComparator getTemplateOrderByComparator(
267 String orderByCol, String orderByType) {
268
269 boolean orderByAsc = false;
270
271 if (orderByType.equals("asc")) {
272 orderByAsc = true;
273 }
274
275 OrderByComparator orderByComparator = null;
276
277 if (orderByCol.equals("id")) {
278 orderByComparator = new TemplateIdComparator(orderByAsc);
279 }
280 else if (orderByCol.equals("modified-date")) {
281 orderByComparator = new TemplateModifiedDateComparator(orderByAsc);
282 }
283
284 return orderByComparator;
285 }
286
287 public Fields mergeFields(Fields newFields, Fields existingFields) {
288 Iterator<Field> itr = newFields.iterator(true);
289
290 while (itr.hasNext()) {
291 Field newField = itr.next();
292
293 Field existingField = existingFields.get(newField.getName());
294
295 if (existingField == null) {
296 existingFields.put(newField);
297 }
298 else {
299 for (Locale locale : newField.getAvailableLocales()) {
300 existingField.setValues(locale, newField.getValues(locale));
301 }
302
303 existingField.setDefaultLocale(newField.getDefaultLocale());
304 }
305
306 }
307
308 return existingFields;
309 }
310
311 public void sendFieldFile(
312 HttpServletRequest request, HttpServletResponse response,
313 Field field, int valueIndex)
314 throws Exception {
315
316 if (field == null) {
317 return;
318 }
319
320 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
321 WebKeys.THEME_DISPLAY);
322
323 DDMStructure structure = field.getDDMStructure();
324
325 Serializable fieldValue = field.getValue(
326 themeDisplay.getLocale(), valueIndex);
327
328 JSONObject fileJSONObject = JSONFactoryUtil.createJSONObject(
329 String.valueOf(fieldValue));
330
331 String fileName = fileJSONObject.getString("name");
332 String filePath = fileJSONObject.getString("path");
333
334 InputStream is = DLStoreUtil.getFileAsStream(
335 structure.getCompanyId(), CompanyConstants.SYSTEM, filePath);
336 long contentLength = DLStoreUtil.getFileSize(
337 structure.getCompanyId(), CompanyConstants.SYSTEM, filePath);
338 String contentType = MimeTypesUtil.getContentType(fileName);
339
340 ServletResponseUtil.sendFile(
341 request, response, fileName, is, contentLength, contentType);
342 }
343
344 public void uploadFieldFile(
345 long structureId, long storageId, BaseModel<?> baseModel,
346 String fieldName, ServiceContext serviceContext)
347 throws Exception {
348
349 uploadFieldFile(
350 structureId, storageId, baseModel, fieldName, StringPool.BLANK,
351 serviceContext);
352 }
353
354 public void uploadFieldFile(
355 long structureId, long storageId, BaseModel<?> baseModel,
356 String fieldName, String fieldNamespace,
357 ServiceContext serviceContext)
358 throws Exception {
359
360 HttpServletRequest request = serviceContext.getRequest();
361
362 if (!(request instanceof UploadRequest)) {
363 return;
364 }
365
366 UploadRequest uploadRequest = (UploadRequest)request;
367
368 Fields fields = StorageEngineUtil.getFields(storageId);
369
370 List<String> fieldNames = getFieldNames(
371 fieldNamespace, fieldName, serviceContext);
372
373 List<Serializable> fieldValues = new ArrayList<Serializable>(
374 fieldNames.size());
375
376 for (String fieldNameValue : fieldNames) {
377 InputStream inputStream = null;
378
379 try {
380 String fileName = uploadRequest.getFileName(fieldNameValue);
381
382 inputStream = uploadRequest.getFileAsStream(fieldName, true);
383
384 if (inputStream != null) {
385 String filePath = storeFieldFile(
386 baseModel, fieldName, inputStream, serviceContext);
387
388 JSONObject recordFileJSONObject =
389 JSONFactoryUtil.createJSONObject();
390
391 recordFileJSONObject.put("name", fileName);
392 recordFileJSONObject.put("path", filePath);
393 recordFileJSONObject.put(
394 "className", baseModel.getModelClassName());
395 recordFileJSONObject.put(
396 "classPK",
397 String.valueOf(baseModel.getPrimaryKeyObj()));
398
399 String fieldValue = recordFileJSONObject.toString();
400
401 fieldValues.add(fieldValue);
402 }
403 else if (fields.contains(fieldName)) {
404 continue;
405 }
406 }
407 finally {
408 StreamUtil.cleanUp(inputStream);
409 }
410 }
411
412 Field field = new Field(
413 structureId, fieldName, fieldValues, serviceContext.getLocale());
414
415 fields.put(field);
416
417 StorageEngineUtil.update(storageId, fields, true, serviceContext);
418 }
419
420 protected DDMStructure getDDMStructure(
421 long ddmStructureId, long ddmTemplateId)
422 throws PortalException, SystemException {
423
424 DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
425 ddmStructureId);
426
427 try {
428 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
429 ddmTemplateId);
430
431
432
433 ddmStructure = (DDMStructure)ddmStructure.clone();
434
435 ddmStructure.setXsd(ddmTemplate.getScript());
436 }
437 catch (NoSuchTemplateException nste) {
438 }
439
440 return ddmStructure;
441 }
442
443 protected List<String> getFieldNames(
444 String fieldNamespace, String fieldName,
445 ServiceContext serviceContext) {
446
447 String[] fieldsDisplayValues = StringUtil.split(
448 (String)serviceContext.getAttribute(
449 fieldNamespace + FIELDS_DISPLAY_NAME));
450
451 List<String> privateFieldNames = ListUtil.fromArray(
452 PropsValues.DYNAMIC_DATA_MAPPING_STRUCTURE_PRIVATE_FIELD_NAMES);
453
454 List<String> fieldNames = new ArrayList<String>();
455
456 if ((fieldsDisplayValues.length == 0) ||
457 privateFieldNames.contains(fieldName)) {
458
459 fieldNames.add(fieldNamespace + fieldName);
460 }
461 else {
462 for (String namespacedFieldName : fieldsDisplayValues) {
463 String fieldNameValue = StringUtil.extractFirst(
464 namespacedFieldName, INSTANCE_SEPARATOR);
465
466 if (fieldNameValue.equals(fieldName)) {
467 fieldNames.add(fieldNamespace + namespacedFieldName);
468 }
469 }
470 }
471
472 return fieldNames;
473 }
474
475 protected List<Serializable> getFieldValues(
476 DDMStructure ddmStructure, String fieldName, String fieldNamespace,
477 ServiceContext serviceContext)
478 throws PortalException, SystemException {
479
480 String fieldDataType = ddmStructure.getFieldDataType(fieldName);
481 String fieldType = ddmStructure.getFieldType(fieldName);
482
483 List<String> fieldNames = getFieldNames(
484 fieldNamespace, fieldName, serviceContext);
485
486 List<Serializable> fieldValues = new ArrayList<Serializable>(
487 fieldNames.size());
488
489 for (String fieldNameValue : fieldNames) {
490 Serializable fieldValue = serviceContext.getAttribute(
491 fieldNameValue);
492
493 if (fieldDataType.equals(FieldConstants.DATE)) {
494 int fieldValueMonth = GetterUtil.getInteger(
495 serviceContext.getAttribute(fieldNameValue + "Month"));
496 int fieldValueDay = GetterUtil.getInteger(
497 serviceContext.getAttribute(fieldNameValue + "Day"));
498 int fieldValueYear = GetterUtil.getInteger(
499 serviceContext.getAttribute(fieldNameValue + "Year"));
500
501 Date fieldValueDate = PortalUtil.getDate(
502 fieldValueMonth, fieldValueDay, fieldValueYear);
503
504 if (fieldValueDate != null) {
505 fieldValue = String.valueOf(fieldValueDate.getTime());
506 }
507 }
508 else if (fieldDataType.equals(FieldConstants.IMAGE) &&
509 Validator.isNull(fieldValue)) {
510
511 HttpServletRequest request = serviceContext.getRequest();
512
513 if (!(request instanceof UploadRequest)) {
514 return null;
515 }
516
517 UploadRequest uploadRequest = (UploadRequest)request;
518
519 File file = uploadRequest.getFile(fieldNameValue);
520
521 try {
522 byte[] bytes = FileUtil.getBytes(file);
523
524 if ((bytes != null) && (bytes.length > 0)) {
525 fieldValue = UnicodeFormatter.bytesToHex(bytes);
526 }
527 }
528 catch (IOException ioe) {
529 return null;
530 }
531 }
532
533 if (Validator.isNull(fieldValue) ||
534 fieldDataType.equals(FieldConstants.FILE_UPLOAD)) {
535
536 return null;
537 }
538
539 if (DDMImpl.TYPE_RADIO.equals(fieldType) ||
540 DDMImpl.TYPE_SELECT.equals(fieldType)) {
541
542 if (fieldValue instanceof String) {
543 fieldValue = new String[] {String.valueOf(fieldValue)};
544 }
545
546 fieldValue = JSONFactoryUtil.serialize(fieldValue);
547 }
548
549 Serializable fieldValueSerializable =
550 FieldConstants.getSerializable(
551 fieldDataType, GetterUtil.getString(fieldValue));
552
553 fieldValues.add(fieldValueSerializable);
554 }
555
556 return fieldValues;
557 }
558
559 protected String storeFieldFile(
560 BaseModel<?> baseModel, String fieldName, InputStream inputStream,
561 ServiceContext serviceContext)
562 throws Exception {
563
564 String dirName = getFileUploadPath(baseModel);
565
566 try {
567 DLStoreUtil.addDirectory(
568 serviceContext.getCompanyId(), CompanyConstants.SYSTEM,
569 dirName);
570 }
571 catch (DuplicateDirectoryException dde) {
572 }
573
574 String fileName = dirName + StringPool.SLASH + fieldName;
575
576 try {
577 DLStoreUtil.addFile(
578 serviceContext.getCompanyId(), CompanyConstants.SYSTEM,
579 fileName, inputStream);
580 }
581 catch (DuplicateFileException dfe) {
582 }
583
584 return fileName;
585 }
586
587 }