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