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