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.TemplateConstants;
029 import com.liferay.portal.kernel.util.Constants;
030 import com.liferay.portal.kernel.util.GetterUtil;
031 import com.liferay.portal.kernel.util.LocaleThreadLocal;
032 import com.liferay.portal.kernel.util.LocaleUtil;
033 import com.liferay.portal.kernel.util.ParamUtil;
034 import com.liferay.portal.kernel.util.PropsKeys;
035 import com.liferay.portal.kernel.util.StringPool;
036 import com.liferay.portal.kernel.util.Validator;
037 import com.liferay.portal.model.Group;
038 import com.liferay.portal.model.PortletConstants;
039 import com.liferay.portal.service.GroupLocalServiceUtil;
040 import com.liferay.portal.service.LayoutServiceUtil;
041 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
042 import com.liferay.portal.service.ServiceContext;
043 import com.liferay.portal.templateparser.Transformer;
044 import com.liferay.portal.theme.ThemeDisplay;
045 import com.liferay.portal.util.PortletKeys;
046 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
047 import com.liferay.portlet.dynamicdatalists.NoSuchRecordException;
048 import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
049 import com.liferay.portlet.dynamicdatalists.model.DDLRecordConstants;
050 import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
051 import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
052 import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
053 import com.liferay.portlet.dynamicdatalists.service.DDLRecordServiceUtil;
054 import com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalServiceUtil;
055 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
056 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
057 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
058 import com.liferay.portlet.dynamicdatamapping.storage.Field;
059 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
060 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
061 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
062 import com.liferay.portlet.dynamicdatamapping.util.DDMImpl;
063 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
064
065 import java.util.ArrayList;
066 import java.util.Date;
067 import java.util.HashMap;
068 import java.util.List;
069 import java.util.Locale;
070 import java.util.Map;
071
072 import javax.portlet.PortletPreferences;
073 import javax.portlet.RenderRequest;
074 import javax.portlet.RenderResponse;
075
076 import javax.servlet.http.HttpServletRequest;
077
078
082 @DoPrivileged
083 public class DDLImpl implements DDL {
084
085 @Override
086 public JSONObject getRecordJSONObject(DDLRecord record) throws Exception {
087 return getRecordJSONObject(record, false);
088 }
089
090 @Override
091 public JSONObject getRecordJSONObject(
092 DDLRecord record, boolean latestRecordVersion)
093 throws Exception {
094
095 DDLRecordSet recordSet = record.getRecordSet();
096
097 DDMStructure ddmStructure = recordSet.getDDMStructure();
098
099 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
100
101 for (String fieldName : ddmStructure.getFieldNames()) {
102 jsonObject.put(fieldName, StringPool.BLANK);
103 }
104
105 jsonObject.put("displayIndex", record.getDisplayIndex());
106 jsonObject.put("recordId", record.getRecordId());
107
108 DDLRecordVersion recordVersion = record.getRecordVersion();
109
110 if (latestRecordVersion) {
111 recordVersion = record.getLatestRecordVersion();
112 }
113
114 Fields fields = StorageEngineUtil.getFields(
115 recordVersion.getDDMStorageId());
116
117 for (Field field : fields) {
118 String fieldName = field.getName();
119 String fieldType = field.getType();
120 Object fieldValue = field.getValue();
121
122 if (fieldValue instanceof Date) {
123 jsonObject.put(fieldName, ((Date)fieldValue).getTime());
124 }
125 else if (fieldType.equals(DDMImpl.TYPE_DDM_DOCUMENTLIBRARY) &&
126 Validator.isNotNull(fieldValue)) {
127
128 JSONObject fieldValueJSONObject =
129 JSONFactoryUtil.createJSONObject(
130 String.valueOf(fieldValue));
131
132 String uuid = fieldValueJSONObject.getString("uuid");
133 long groupId = fieldValueJSONObject.getLong("groupId");
134
135 fieldValueJSONObject.put(
136 "title", getFileEntryTitle(uuid, groupId));
137
138 jsonObject.put(fieldName, fieldValueJSONObject.toString());
139 }
140 else if (fieldType.equals(DDMImpl.TYPE_DDM_LINK_TO_PAGE) &&
141 Validator.isNotNull(fieldValue)) {
142
143 JSONObject fieldValueJSONObject =
144 JSONFactoryUtil.createJSONObject(
145 String.valueOf(fieldValue));
146
147 long groupId = fieldValueJSONObject.getLong("groupId");
148 boolean privateLayout = fieldValueJSONObject.getBoolean(
149 "privateLayout");
150 long layoutId = fieldValueJSONObject.getLong("layoutId");
151 Locale locale = LocaleThreadLocal.getThemeDisplayLocale();
152
153 String layoutName = getLayoutName(
154 groupId, privateLayout, layoutId,
155 LanguageUtil.getLanguageId(locale));
156
157 fieldValueJSONObject.put("name", layoutName);
158
159 jsonObject.put(fieldName, fieldValueJSONObject.toString());
160 }
161 else if ((fieldType.equals(DDMImpl.TYPE_RADIO) ||
162 fieldType.equals(DDMImpl.TYPE_SELECT)) &&
163 Validator.isNotNull(fieldValue)) {
164
165 fieldValue = JSONFactoryUtil.createJSONArray(
166 String.valueOf(fieldValue));
167
168 jsonObject.put(fieldName, (JSONArray)fieldValue);
169 }
170 else {
171 jsonObject.put(fieldName, String.valueOf(fieldValue));
172 }
173 }
174
175 return jsonObject;
176 }
177
178 @Override
179 public List<DDLRecord> getRecords(Hits hits) throws Exception {
180 List<DDLRecord> records = new ArrayList<DDLRecord>();
181
182 List<com.liferay.portal.kernel.search.Document> documents =
183 hits.toList();
184
185 for (com.liferay.portal.kernel.search.Document document : documents) {
186 long recordId = GetterUtil.getLong(
187 document.get(
188 com.liferay.portal.kernel.search.Field.ENTRY_CLASS_PK));
189
190 try {
191 DDLRecord record = DDLRecordLocalServiceUtil.getRecord(
192 recordId);
193
194 records.add(record);
195 }
196 catch (NoSuchRecordException nsre) {
197 if (_log.isWarnEnabled()) {
198 _log.warn(
199 "DDL record index is stale and contains record " +
200 recordId);
201 }
202
203 Indexer indexer = IndexerRegistryUtil.getIndexer(
204 DDLRecord.class);
205
206 long companyId = GetterUtil.getLong(
207 document.get(
208 com.liferay.portal.kernel.search.Field.COMPANY_ID));
209
210 indexer.delete(companyId, document.getUID());
211 }
212 }
213
214 return records;
215 }
216
217 @Override
218 public JSONArray getRecordSetJSONArray(DDLRecordSet recordSet)
219 throws Exception {
220
221 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
222
223 DDMStructure ddmStructure = recordSet.getDDMStructure();
224
225 Map<String, Map<String, String>> fieldsMap =
226 ddmStructure.getFieldsMap();
227
228 for (Map<String, String> fields : fieldsMap.values()) {
229 String name = fields.get(FieldConstants.NAME);
230
231 if (ddmStructure.isFieldPrivate(name)) {
232 continue;
233 }
234
235 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
236
237 String dataType = fields.get(FieldConstants.DATA_TYPE);
238
239 jsonObject.put("dataType", dataType);
240
241 boolean editable = GetterUtil.getBoolean(
242 fields.get(FieldConstants.EDITABLE), true);
243
244 jsonObject.put("editable", editable);
245
246 String label = fields.get(FieldConstants.LABEL);
247
248 jsonObject.put("label", label);
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 @Override
273 public JSONArray getRecordsJSONArray(DDLRecordSet recordSet)
274 throws Exception {
275
276 return getRecordsJSONArray(recordSet.getRecords(), false);
277 }
278
279 @Override
280 public JSONArray getRecordsJSONArray(List<DDLRecord> records)
281 throws Exception {
282
283 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
284
285 for (DDLRecord record : records) {
286 JSONObject jsonObject = getRecordJSONObject(record);
287
288 jsonArray.put(jsonObject);
289 }
290
291 return jsonArray;
292 }
293
294 @Override
295 public JSONArray getRecordsJSONArray(
296 List<DDLRecord> records, boolean latestRecordVersion)
297 throws Exception {
298
299 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
300
301 for (DDLRecord record : records) {
302 JSONObject jsonObject = getRecordJSONObject(
303 record, latestRecordVersion);
304
305 jsonArray.put(jsonObject);
306 }
307
308 return jsonArray;
309 }
310
311 @Override
312 public String getTemplateContent(
313 long ddmTemplateId, DDLRecordSet recordSet,
314 ThemeDisplay themeDisplay, RenderRequest renderRequest,
315 RenderResponse renderResponse)
316 throws Exception {
317
318 Map<String, Object> contextObjects = new HashMap<String, Object>();
319
320 contextObjects.put(
321 DDLConstants.RESERVED_DDM_STRUCTURE_ID,
322 recordSet.getDDMStructureId());
323 contextObjects.put(
324 DDLConstants.RESERVED_DDM_TEMPLATE_ID, ddmTemplateId);
325 contextObjects.put(
326 DDLConstants.RESERVED_RECORD_SET_DESCRIPTION,
327 recordSet.getDescription(themeDisplay.getLocale()));
328 contextObjects.put(
329 DDLConstants.RESERVED_RECORD_SET_ID, recordSet.getRecordSetId());
330 contextObjects.put(
331 DDLConstants.RESERVED_RECORD_SET_NAME,
332 recordSet.getName(themeDisplay.getLocale()));
333 contextObjects.put(TemplateConstants.TEMPLATE_ID, ddmTemplateId);
334
335 String viewMode = ParamUtil.getString(renderRequest, "viewMode");
336
337 if (Validator.isNull(viewMode)) {
338 viewMode = Constants.VIEW;
339 }
340
341 contextObjects.put("viewMode", viewMode);
342
343 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
344 ddmTemplateId);
345
346 contextObjects.put(
347 TemplateConstants.CLASS_NAME_ID, ddmTemplate.getClassNameId());
348
349 return _transformer.transform(
350 themeDisplay, contextObjects, ddmTemplate.getScript(),
351 ddmTemplate.getLanguage());
352 }
353
354 @Override
355 public boolean isEditable(
356 HttpServletRequest request, String portletId, long groupId)
357 throws Exception {
358
359 boolean defaultValue = ParamUtil.getBoolean(request, "editable", true);
360
361 return isEditable(portletId, groupId, defaultValue);
362 }
363
364 @Override
365 public boolean isEditable(
366 PortletPreferences preferences, String portletId, long groupId)
367 throws Exception {
368
369 boolean defaultValue = GetterUtil.getBoolean(
370 preferences.getValue("editable", null), true);
371
372 return isEditable(portletId, groupId, defaultValue);
373 }
374
375 @Override
376 public DDLRecord updateRecord(
377 long recordId, long recordSetId, boolean mergeFields,
378 boolean checkPermission, ServiceContext serviceContext)
379 throws Exception {
380
381 DDLRecord record = DDLRecordLocalServiceUtil.fetchRecord(recordId);
382
383 PortletPreferences preferences =
384 PortletPreferencesLocalServiceUtil.getPreferences(
385 serviceContext.getPortletPreferencesIds());
386
387 if (!isEditable(
388 preferences, serviceContext.getPortletId(),
389 serviceContext.getScopeGroupId())) {
390
391 return record;
392 }
393
394 boolean majorVersion = ParamUtil.getBoolean(
395 serviceContext, "majorVersion");
396
397 DDLRecordSet recordSet = DDLRecordSetLocalServiceUtil.getDDLRecordSet(
398 recordSetId);
399
400 DDMStructure ddmStructure = recordSet.getDDMStructure();
401
402 Fields fields = DDMUtil.getFields(
403 ddmStructure.getStructureId(), serviceContext);
404
405 if (record != null) {
406 if (checkPermission) {
407 record = DDLRecordServiceUtil.updateRecord(
408 recordId, majorVersion,
409 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
410 mergeFields, serviceContext);
411 }
412 else {
413 record = DDLRecordLocalServiceUtil.updateRecord(
414 serviceContext.getUserId(), recordId, majorVersion,
415 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
416 mergeFields, serviceContext);
417 }
418 }
419 else {
420 if (checkPermission) {
421 record = DDLRecordServiceUtil.addRecord(
422 serviceContext.getScopeGroupId(), recordSetId,
423 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
424 serviceContext);
425 }
426 else {
427 record = DDLRecordLocalServiceUtil.addRecord(
428 serviceContext.getUserId(),
429 serviceContext.getScopeGroupId(), recordSetId,
430 DDLRecordConstants.DISPLAY_INDEX_DEFAULT, fields,
431 serviceContext);
432 }
433 }
434
435 return record;
436 }
437
438 @Override
439 public DDLRecord updateRecord(
440 long recordId, long recordSetId, boolean mergeFields,
441 ServiceContext serviceContext)
442 throws Exception {
443
444 return updateRecord(
445 recordId, recordSetId, mergeFields, true, serviceContext);
446 }
447
448 protected String getFileEntryTitle(String uuid, long groupId) {
449 try {
450 FileEntry fileEntry =
451 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
452 uuid, groupId);
453
454 return fileEntry.getTitle();
455 }
456 catch (Exception e) {
457 return LanguageUtil.format(
458 LocaleUtil.getSiteDefault(), "is-temporarily-unavailable",
459 "content");
460 }
461 }
462
463 protected String getLayoutName(
464 long groupId, boolean privateLayout, long layoutId, String languageId) {
465
466 try {
467 return LayoutServiceUtil.getLayoutName(
468 groupId, privateLayout, layoutId, languageId);
469 }
470 catch (Exception e) {
471 return LanguageUtil.format(
472 LocaleUtil.getSiteDefault(), "is-temporarily-unavailable",
473 "content");
474 }
475 }
476
477 protected boolean isEditable(
478 String portletId, long groupId, boolean defaultValue)
479 throws Exception {
480
481 String rootPortletId = PortletConstants.getRootPortletId(portletId);
482
483 if (rootPortletId.equals(PortletKeys.DYNAMIC_DATA_LISTS)) {
484 return true;
485 }
486
487 Group group = GroupLocalServiceUtil.fetchGroup(groupId);
488
489 if ((group == null) || group.isInStagingPortlet(portletId)) {
490 return false;
491 }
492
493 return defaultValue;
494 }
495
496 private static Log _log = LogFactoryUtil.getLog(DDLImpl.class);
497
498 private Transformer _transformer = new Transformer(
499 PropsKeys.DYNAMIC_DATA_LISTS_ERROR_TEMPLATE, true);
500
501 }