001
014
015 package com.liferay.portlet.dynamicdatalists.util;
016
017 import com.liferay.portal.kernel.json.JSONArray;
018 import com.liferay.portal.kernel.json.JSONFactoryUtil;
019 import com.liferay.portal.kernel.json.JSONObject;
020 import com.liferay.portal.kernel.language.LanguageUtil;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.repository.model.FileEntry;
024 import com.liferay.portal.kernel.search.Hits;
025 import com.liferay.portal.kernel.search.Indexer;
026 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
027 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
028 import com.liferay.portal.kernel.template.TemplateContextType;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.LocaleUtil;
031 import com.liferay.portal.kernel.util.ParamUtil;
032 import com.liferay.portal.kernel.util.PropsKeys;
033 import com.liferay.portal.kernel.util.StringPool;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.kernel.xml.Document;
037 import com.liferay.portal.kernel.xml.Element;
038 import com.liferay.portal.kernel.xml.SAXReaderUtil;
039 import com.liferay.portal.model.Group;
040 import com.liferay.portal.model.PortletConstants;
041 import com.liferay.portal.service.GroupLocalServiceUtil;
042 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
043 import com.liferay.portal.service.ServiceContext;
044 import com.liferay.portal.templateparser.Transformer;
045 import com.liferay.portal.theme.ThemeDisplay;
046 import com.liferay.portal.util.PortletKeys;
047 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
048 import com.liferay.portlet.dynamicdatalists.NoSuchRecordException;
049 import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
050 import com.liferay.portlet.dynamicdatalists.model.DDLRecordConstants;
051 import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
052 import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
053 import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
054 import com.liferay.portlet.dynamicdatalists.service.DDLRecordServiceUtil;
055 import com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalServiceUtil;
056 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
057 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
058 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
059 import com.liferay.portlet.dynamicdatamapping.storage.Field;
060 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
061 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
062 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
063 import com.liferay.portlet.dynamicdatamapping.util.DDMImpl;
064 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
065 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
066 import com.liferay.portlet.journal.util.JournalUtil;
067 import com.liferay.util.portlet.PortletRequestUtil;
068
069 import java.util.ArrayList;
070 import java.util.Date;
071 import java.util.Iterator;
072 import java.util.List;
073 import java.util.Map;
074
075 import javax.portlet.PortletPreferences;
076 import javax.portlet.RenderRequest;
077 import javax.portlet.RenderResponse;
078
079 import javax.servlet.http.HttpServletRequest;
080 import javax.servlet.http.HttpServletResponse;
081
082
086 @DoPrivileged
087 public class DDLImpl implements DDL {
088
089 public void addAllReservedEls(
090 Element rootElement, Map<String, String> tokens,
091 DDLRecordSet recordSet) {
092
093 JournalUtil.addReservedEl(
094 rootElement, tokens, DDLConstants.RESERVED_RECORD_SET_ID,
095 String.valueOf(recordSet.getRecordSetId()));
096
097 JournalUtil.addReservedEl(
098 rootElement, tokens, DDLConstants.RESERVED_RECORD_SET_NAME,
099 recordSet.getName());
100
101 JournalUtil.addReservedEl(
102 rootElement, tokens, DDLConstants.RESERVED_RECORD_SET_DESCRIPTION,
103 recordSet.getDescription());
104
105 JournalUtil.addReservedEl(
106 rootElement, tokens, DDLConstants.RESERVED_DDM_STRUCTURE_ID,
107 String.valueOf(recordSet.getDDMStructureId()));
108 }
109
110 public JSONObject getRecordJSONObject(DDLRecord record) throws Exception {
111 return getRecordJSONObject(record, false);
112 }
113
114 public JSONObject getRecordJSONObject(
115 DDLRecord record, boolean latestRecordVersion)
116 throws Exception {
117
118 DDLRecordSet recordSet = record.getRecordSet();
119
120 DDMStructure ddmStructure = recordSet.getDDMStructure();
121
122 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
123
124 for (String fieldName : ddmStructure.getFieldNames()) {
125 jsonObject.put(fieldName, StringPool.BLANK);
126 }
127
128 jsonObject.put("displayIndex", record.getDisplayIndex());
129 jsonObject.put("recordId", record.getRecordId());
130
131 DDLRecordVersion recordVersion = record.getRecordVersion();
132
133 if (latestRecordVersion) {
134 recordVersion = record.getLatestRecordVersion();
135 }
136
137 Fields fields = StorageEngineUtil.getFields(
138 recordVersion.getDDMStorageId());
139
140 Iterator<Field> itr = fields.iterator();
141
142 while (itr.hasNext()) {
143 Field field = itr.next();
144
145 String fieldName = field.getName();
146 String fieldType = field.getType();
147 Object fieldValue = field.getValue();
148
149 if (fieldValue instanceof Date) {
150 jsonObject.put(fieldName, ((Date)fieldValue).getTime());
151 }
152 else if (fieldType.equals(DDMImpl.TYPE_DDM_DOCUMENTLIBRARY) &&
153 Validator.isNotNull(fieldValue)) {
154
155 JSONObject fieldValueJSONObject =
156 JSONFactoryUtil.createJSONObject(
157 String.valueOf(fieldValue));
158
159 String uuid = fieldValueJSONObject.getString("uuid");
160 long groupId = fieldValueJSONObject.getLong("groupId");
161
162 fieldValueJSONObject.put(
163 "title", getFileEntryTitle(uuid, groupId));
164
165 jsonObject.put(fieldName, fieldValueJSONObject.toString());
166 }
167 else if ((fieldType.equals(DDMImpl.TYPE_RADIO) ||
168 fieldType.equals(DDMImpl.TYPE_SELECT)) &&
169 Validator.isNotNull(fieldValue)) {
170
171 fieldValue = JSONFactoryUtil.createJSONArray(
172 String.valueOf(fieldValue));
173
174 jsonObject.put(fieldName, (JSONArray)fieldValue);
175 }
176 else {
177 jsonObject.put(fieldName, String.valueOf(fieldValue));
178 }
179 }
180
181 return jsonObject;
182 }
183
184 public List<DDLRecord> getRecords(Hits hits) throws Exception {
185 List<DDLRecord> records = new ArrayList<DDLRecord>();
186
187 List<com.liferay.portal.kernel.search.Document> documents =
188 hits.toList();
189
190 for (com.liferay.portal.kernel.search.Document document : documents) {
191 long recordId = GetterUtil.getLong(
192 document.get(
193 com.liferay.portal.kernel.search.Field.ENTRY_CLASS_PK));
194
195 try {
196 DDLRecord record = DDLRecordLocalServiceUtil.getRecord(
197 recordId);
198
199 records.add(record);
200 }
201 catch (NoSuchRecordException nsre) {
202 if (_log.isWarnEnabled()) {
203 _log.warn(
204 "DDL record index is stale and contains record " +
205 recordId);
206 }
207
208 Indexer indexer = IndexerRegistryUtil.getIndexer(
209 DDLRecord.class);
210
211 long companyId = GetterUtil.getLong(
212 document.get(
213 com.liferay.portal.kernel.search.Field.COMPANY_ID));
214
215 indexer.delete(companyId, document.getUID());
216 }
217 }
218
219 return records;
220 }
221
222 public JSONArray getRecordSetJSONArray(DDLRecordSet recordSet)
223 throws Exception {
224
225 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
226
227 DDMStructure ddmStructure = recordSet.getDDMStructure();
228
229 Map<String, Map<String, String>> fieldsMap =
230 ddmStructure.getFieldsMap();
231
232 for (Map<String, String> fields : fieldsMap.values()) {
233 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
234
235 String dataType = fields.get(FieldConstants.DATA_TYPE);
236
237 jsonObject.put("dataType", dataType);
238
239 boolean editable = GetterUtil.getBoolean(
240 fields.get(FieldConstants.EDITABLE), true);
241
242 jsonObject.put("editable", editable);
243
244 String label = fields.get(FieldConstants.LABEL);
245
246 jsonObject.put("label", label);
247
248 String name = fields.get(FieldConstants.NAME);
249
250 jsonObject.put("name", name);
251
252 boolean required = GetterUtil.getBoolean(
253 fields.get(FieldConstants.REQUIRED));
254
255 jsonObject.put("required", required);
256
257 boolean sortable = GetterUtil.getBoolean(
258 fields.get(FieldConstants.SORTABLE), true);
259
260 jsonObject.put("sortable", sortable);
261
262 String type = fields.get(FieldConstants.TYPE);
263
264 jsonObject.put("type", type);
265
266 jsonArray.put(jsonObject);
267 }
268
269 return jsonArray;
270 }
271
272 public JSONArray getRecordsJSONArray(DDLRecordSet recordSet)
273 throws Exception {
274
275 return getRecordsJSONArray(recordSet.getRecords(), false);
276 }
277
278 public JSONArray getRecordsJSONArray(List<DDLRecord> records)
279 throws Exception {
280
281 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
282
283 for (DDLRecord record : records) {
284 JSONObject jsonObject = getRecordJSONObject(record);
285
286 jsonArray.put(jsonObject);
287 }
288
289 return jsonArray;
290 }
291
292 public JSONArray getRecordsJSONArray(
293 List<DDLRecord> records, boolean latestRecordVersion)
294 throws Exception {
295
296 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
297
298 for (DDLRecord record : records) {
299 JSONObject jsonObject = getRecordJSONObject(
300 record, latestRecordVersion);
301
302 jsonArray.put(jsonObject);
303 }
304
305 return jsonArray;
306 }
307
308 public String getTemplateContent(
309 long ddmTemplateId, DDLRecordSet recordSet,
310 ThemeDisplay themeDisplay, RenderRequest renderRequest,
311 RenderResponse renderResponse)
312 throws Exception {
313
314 String viewMode = ParamUtil.getString(renderRequest, "viewMode");
315
316 String languageId = LanguageUtil.getLanguageId(renderRequest);
317
318 String xmlRequest = PortletRequestUtil.toXML(
319 renderRequest, renderResponse);
320
321 if (Validator.isNull(xmlRequest)) {
322 xmlRequest = "<request />";
323 }
324
325 Map<String, String> tokens = JournalUtil.getTokens(
326 recordSet.getGroupId(), themeDisplay, xmlRequest);
327
328 tokens.put("template_id", StringUtil.valueOf(ddmTemplateId));
329
330 String xml = StringPool.BLANK;
331
332 Document document = SAXReaderUtil.createDocument();
333
334 Element rootElement = document.addElement("root");
335
336 Document requestDocument = SAXReaderUtil.read(xmlRequest);
337
338 rootElement.add(requestDocument.getRootElement().createCopy());
339
340 addAllReservedEls(rootElement, tokens, recordSet);
341
342 xml = DDMXMLUtil.formatXML(document);
343
344 DDMTemplate template = DDMTemplateLocalServiceUtil.getTemplate(
345 ddmTemplateId);
346
347 return _transformer.transform(
348 themeDisplay, tokens, viewMode, languageId, xml,
349 template.getScript(), template.getLanguage());
350 }
351
352 public boolean isEditable(
353 HttpServletRequest request, String portletId, long groupId)
354 throws Exception {
355
356 boolean defaultValue = ParamUtil.getBoolean(request, "editable", true);
357
358 return isEditable(portletId, groupId, defaultValue);
359 }
360
361 public boolean isEditable(
362 PortletPreferences preferences, String portletId, long groupId)
363 throws Exception {
364
365 boolean defaultValue = GetterUtil.getBoolean(
366 preferences.getValue("editable", null), true);
367
368 return isEditable(portletId, groupId, defaultValue);
369 }
370
371 public void sendRecordFileUpload(
372 HttpServletRequest request, HttpServletResponse response,
373 DDLRecord record, String fieldName, int valueIndex)
374 throws Exception {
375
376 Field field = record.getField(fieldName);
377
378 DDMUtil.sendFieldFile(request, response, field, valueIndex);
379 }
380
381 public void sendRecordFileUpload(
382 HttpServletRequest request, HttpServletResponse response,
383 long recordId, String fieldName, int valueIndex)
384 throws Exception {
385
386 DDLRecord record = DDLRecordServiceUtil.getRecord(recordId);
387
388 sendRecordFileUpload(request, response, record, fieldName, valueIndex);
389 }
390
391 public DDLRecord updateRecord(
392 long recordId, long recordSetId, boolean mergeFields,
393 boolean checkPermission, ServiceContext serviceContext)
394 throws Exception {
395
396 DDLRecord record = DDLRecordLocalServiceUtil.fetchRecord(recordId);
397
398 PortletPreferences preferences =
399 PortletPreferencesLocalServiceUtil.getPreferences(
400 serviceContext.getPortletPreferencesIds());
401
402 if (!isEditable(
403 preferences, serviceContext.getPortletId(),
404 serviceContext.getScopeGroupId())) {
405
406 return record;
407 }
408
409 boolean majorVersion = ParamUtil.getBoolean(
410 serviceContext, "majorVersion");
411
412 DDLRecordSet recordSet = DDLRecordSetLocalServiceUtil.getDDLRecordSet(
413 recordSetId);
414
415 DDMStructure ddmStructure = recordSet.getDDMStructure();
416
417 Fields fields = DDMUtil.getFields(
418 ddmStructure.getStructureId(), serviceContext);
419
420 if (record != null) {
421 if (checkPermission) {
422 record = DDLRecordServiceUtil.updateRecord(
423 recordId, majorVersion,
424 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
425 mergeFields, serviceContext);
426 }
427 else {
428 record = DDLRecordLocalServiceUtil.updateRecord(
429 serviceContext.getUserId(), recordId, majorVersion,
430 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
431 mergeFields, serviceContext);
432 }
433 }
434 else {
435 if (checkPermission) {
436 record = DDLRecordServiceUtil.addRecord(
437 serviceContext.getScopeGroupId(), recordSetId,
438 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
439 serviceContext);
440 }
441 else {
442 record = DDLRecordLocalServiceUtil.addRecord(
443 serviceContext.getUserId(),
444 serviceContext.getScopeGroupId(), recordSetId,
445 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
446 serviceContext);
447 }
448
449 }
450
451 uploadRecordFieldFiles(record, serviceContext);
452
453 return record;
454 }
455
456 public DDLRecord updateRecord(
457 long recordId, long recordSetId, boolean mergeFields,
458 ServiceContext serviceContext)
459 throws Exception {
460
461 return updateRecord(
462 recordId, recordSetId, mergeFields, true, serviceContext);
463 }
464
465 public void uploadRecordFieldFile(
466 DDLRecord record, String fieldName, ServiceContext serviceContext)
467 throws Exception {
468
469 DDLRecordSet recordSet = record.getRecordSet();
470
471 DDMStructure ddmStructure = recordSet.getDDMStructure();
472
473 DDLRecordVersion recordVersion = record.getLatestRecordVersion();
474
475 DDMUtil.uploadFieldFile(
476 ddmStructure.getStructureId(), recordVersion.getDDMStorageId(),
477 record, fieldName, serviceContext);
478 }
479
480 protected String getFileEntryTitle(String uuid, long groupId) {
481 try {
482 FileEntry fileEntry =
483 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
484 uuid, groupId);
485
486 return fileEntry.getTitle();
487 }
488 catch (Exception e) {
489 return LanguageUtil.format(
490 LocaleUtil.getDefault(), "is-temporarily-unavailable",
491 "content");
492 }
493 }
494
495 protected boolean isEditable(
496 String portletId, long groupId, boolean defaultValue)
497 throws Exception {
498
499 String rootPortletId = PortletConstants.getRootPortletId(portletId);
500
501 if (rootPortletId.equals(PortletKeys.DYNAMIC_DATA_LISTS)) {
502 return true;
503 }
504
505 Group group = GroupLocalServiceUtil.fetchGroup(groupId);
506
507 if ((group == null) || group.isInStagingPortlet(portletId)) {
508 return false;
509 }
510
511 return defaultValue;
512 }
513
514 protected void uploadRecordFieldFiles(
515 DDLRecord record, ServiceContext serviceContext)
516 throws Exception {
517
518 DDLRecordSet recordSet = record.getRecordSet();
519
520 DDMStructure ddmStructure = recordSet.getDDMStructure();
521
522 for (String fieldName : ddmStructure.getFieldNames()) {
523 String fieldDataType = ddmStructure.getFieldDataType(fieldName);
524
525 if (fieldDataType.equals(FieldConstants.FILE_UPLOAD)) {
526 uploadRecordFieldFile(record, fieldName, serviceContext);
527 }
528 }
529 }
530
531 private static Log _log = LogFactoryUtil.getLog(DDLImpl.class);
532
533 private Transformer _transformer = new Transformer(
534 PropsKeys.DYNAMIC_DATA_LISTS_TRANSFORMER_LISTENER,
535 PropsKeys.DYNAMIC_DATA_LISTS_ERROR_TEMPLATE,
536 TemplateContextType.STANDARD);
537
538 }