001
014
015 package com.liferay.portlet.dynamicdatamapping.lar;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
019 import com.liferay.portal.kernel.lar.PortletDataContext;
020 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
021 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.util.FileUtil;
025 import com.liferay.portal.kernel.util.GetterUtil;
026 import com.liferay.portal.kernel.util.LocaleUtil;
027 import com.liferay.portal.kernel.util.LocalizationUtil;
028 import com.liferay.portal.kernel.util.MapUtil;
029 import com.liferay.portal.kernel.util.StringBundler;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.kernel.xml.Document;
033 import com.liferay.portal.kernel.xml.Element;
034 import com.liferay.portal.kernel.xml.SAXReaderUtil;
035 import com.liferay.portal.model.Image;
036 import com.liferay.portal.service.ServiceContext;
037 import com.liferay.portal.service.UserLocalServiceUtil;
038 import com.liferay.portal.service.persistence.ImageUtil;
039 import com.liferay.portal.util.PortalUtil;
040 import com.liferay.portal.util.PortletKeys;
041 import com.liferay.portlet.dynamicdatamapping.TemplateDuplicateTemplateKeyException;
042 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
043 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
044 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
045 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
046 import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureUtil;
047 import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMTemplateUtil;
048
049 import java.io.File;
050
051 import java.util.List;
052 import java.util.Locale;
053 import java.util.Map;
054
055 import javax.portlet.PortletPreferences;
056
057
060 public class DDMPortletDataHandlerImpl extends BasePortletDataHandler {
061
062 public static void exportStructure(
063 PortletDataContext portletDataContext, Element structuresElement,
064 DDMStructure structure)
065 throws Exception {
066
067 String path = getStructurePath(portletDataContext, structure);
068
069 if (!portletDataContext.isPathNotProcessed(path)) {
070 return;
071 }
072
073 Element structureElement = structuresElement.addElement("structure");
074
075 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
076 structure.getCompanyId());
077
078 if (defaultUserId == structure.getUserId()) {
079 structureElement.addAttribute("preloaded", "true");
080 }
081
082 portletDataContext.addClassedModel(
083 structureElement, path, structure, _NAMESPACE);
084 }
085
086 public static void exportTemplate(
087 PortletDataContext portletDataContext, Element templatesElement,
088 DDMTemplate template)
089 throws Exception {
090
091 String path = getTemplatePath(portletDataContext, template);
092
093 exportTemplate(portletDataContext, templatesElement, path, template);
094 }
095
096 public static void exportTemplate(
097 PortletDataContext portletDataContext, Element templatesElement,
098 String path, DDMTemplate template)
099 throws Exception {
100
101 if (!portletDataContext.isPathNotProcessed(path)) {
102 return;
103 }
104
105
106
107
108 template = (DDMTemplate)template.clone();
109
110 Element templateElement = templatesElement.addElement("template");
111
112 if (template.isSmallImage() &&
113 Validator.isNull(template.getSmallImageURL())) {
114
115 Image smallImage = ImageUtil.fetchByPrimaryKey(
116 template.getSmallImageId());
117
118 if (smallImage != null) {
119 String smallImagePath = getTemplateSmallImagePath(
120 portletDataContext, template);
121
122 templateElement.addAttribute(
123 "small-image-path", smallImagePath);
124
125 template.setSmallImageType(smallImage.getType());
126
127 portletDataContext.addZipEntry(
128 smallImagePath, smallImage.getTextObj());
129 }
130 }
131
132 portletDataContext.addClassedModel(
133 templateElement, path, template, _NAMESPACE);
134 }
135
136 public static void importStructure(
137 PortletDataContext portletDataContext, Element structureElement)
138 throws Exception {
139
140 String path = structureElement.attributeValue("path");
141
142 if (!portletDataContext.isPathNotProcessed(path)) {
143 return;
144 }
145
146 DDMStructure structure =
147 (DDMStructure)portletDataContext.getZipEntryAsObject(
148 structureElement, path);
149
150 prepareLanguagesForImport(structure);
151
152 long userId = portletDataContext.getUserId(structure.getUserUuid());
153
154 Map<Long, Long> structureIds =
155 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
156 DDMStructure.class);
157
158 ServiceContext serviceContext = portletDataContext.createServiceContext(
159 structureElement, structure, _NAMESPACE);
160
161 DDMStructure importedStructure = null;
162
163 if (portletDataContext.isDataStrategyMirror()) {
164 boolean preloaded = GetterUtil.getBoolean(
165 structureElement.attributeValue("preloaded"));
166
167 DDMStructure existingStructure = null;
168
169 if (!preloaded) {
170 existingStructure = DDMStructureUtil.fetchByUUID_G(
171 structure.getUuid(), portletDataContext.getScopeGroupId());
172 }
173 else {
174 existingStructure = DDMStructureUtil.fetchByG_S(
175 portletDataContext.getScopeGroupId(),
176 structure.getStructureKey());
177 }
178
179 if (existingStructure == null) {
180 serviceContext.setUuid(structure.getUuid());
181
182 importedStructure = DDMStructureLocalServiceUtil.addStructure(
183 userId, portletDataContext.getScopeGroupId(),
184 structure.getParentStructureId(),
185 structure.getClassNameId(), structure.getStructureKey(),
186 structure.getNameMap(), structure.getDescriptionMap(),
187 structure.getXsd(), structure.getStorageType(),
188 structure.getType(), serviceContext);
189 }
190 else {
191 importedStructure =
192 DDMStructureLocalServiceUtil.updateStructure(
193 existingStructure.getStructureId(),
194 structure.getParentStructureId(),
195 structure.getNameMap(), structure.getDescriptionMap(),
196 structure.getXsd(), serviceContext);
197 }
198 }
199 else {
200 importedStructure = DDMStructureLocalServiceUtil.addStructure(
201 userId, portletDataContext.getScopeGroupId(),
202 structure.getParentStructureId(), structure.getClassNameId(),
203 structure.getStructureKey(), structure.getNameMap(),
204 structure.getDescriptionMap(), structure.getXsd(),
205 structure.getStorageType(), structure.getType(),
206 serviceContext);
207 }
208
209 portletDataContext.importClassedModel(
210 structure, importedStructure, _NAMESPACE);
211
212 structureIds.put(
213 structure.getStructureId(), importedStructure.getStructureId());
214 }
215
216 public static void importTemplate(
217 PortletDataContext portletDataContext, Element templateElement)
218 throws Exception {
219
220 String path = templateElement.attributeValue("path");
221
222 if (!portletDataContext.isPathNotProcessed(path)) {
223 return;
224 }
225
226 DDMTemplate template =
227 (DDMTemplate)portletDataContext.getZipEntryAsObject(
228 templateElement, path);
229
230 long userId = portletDataContext.getUserId(template.getUserUuid());
231
232 Map<Long, Long> structureIds =
233 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
234 DDMStructure.class);
235
236 long classPK = MapUtil.getLong(
237 structureIds, template.getClassPK(), template.getClassPK());
238
239 File smallFile = null;
240
241 String smallImagePath = templateElement.attributeValue(
242 "small-image-path");
243
244 if (template.isSmallImage() && Validator.isNotNull(smallImagePath)) {
245 byte[] bytes = portletDataContext.getZipEntryAsByteArray(
246 smallImagePath);
247
248 if (bytes != null) {
249 smallFile = FileUtil.createTempFile(
250 template.getSmallImageType());
251
252 FileUtil.write(smallFile, bytes);
253 }
254 }
255
256 ServiceContext serviceContext = portletDataContext.createServiceContext(
257 templateElement, template, _NAMESPACE);
258
259 DDMTemplate importedTemplate = null;
260
261 if (portletDataContext.isDataStrategyMirror()) {
262 DDMTemplate existingTemplate = DDMTemplateUtil.fetchByUUID_G(
263 template.getUuid(), portletDataContext.getScopeGroupId());
264
265 if (existingTemplate == null) {
266 serviceContext.setUuid(template.getUuid());
267
268 importedTemplate = addTemplate(
269 userId, portletDataContext.getScopeGroupId(), template,
270 classPK, smallFile, serviceContext);
271 }
272 else {
273 importedTemplate = DDMTemplateLocalServiceUtil.updateTemplate(
274 existingTemplate.getTemplateId(), template.getNameMap(),
275 template.getDescriptionMap(), template.getType(),
276 template.getMode(), template.getLanguage(),
277 template.getScript(), template.isCacheable(),
278 template.isSmallImage(), template.getSmallImageURL(),
279 smallFile, serviceContext);
280 }
281 }
282 else {
283 importedTemplate = addTemplate(
284 userId, portletDataContext.getScopeGroupId(), template, classPK,
285 smallFile, serviceContext);
286 }
287
288 portletDataContext.importClassedModel(
289 template, importedTemplate, _NAMESPACE);
290 }
291
292 @Override
293 public PortletDataHandlerControl[] getExportControls() {
294 return new PortletDataHandlerControl[] {_structures, _templates};
295 }
296
297 @Override
298 public PortletDataHandlerControl[] getImportControls() {
299 return new PortletDataHandlerControl[] {_structures, _templates};
300 }
301
302 @Override
303 public boolean isAlwaysExportable() {
304 return _ALWAYS_EXPORTABLE;
305 }
306
307 @Override
308 public boolean isDataLocalized() {
309 return _DATA_LOCALIZED;
310 }
311
312 protected static DDMTemplate addTemplate(
313 long userId, long groupId, DDMTemplate template, long classPK,
314 File smallFile, ServiceContext serviceContext)
315 throws Exception {
316
317 DDMTemplate newTemplate = null;
318
319 try {
320 return DDMTemplateLocalServiceUtil.addTemplate(
321 userId, groupId, template.getClassNameId(), classPK,
322 template.getTemplateKey(), template.getNameMap(),
323 template.getDescriptionMap(), template.getType(),
324 template.getMode(), template.getLanguage(),
325 template.getScript(), template.isCacheable(),
326 template.isSmallImage(), template.getSmallImageURL(), smallFile,
327 serviceContext);
328 }
329 catch (TemplateDuplicateTemplateKeyException tdtke) {
330 newTemplate = DDMTemplateLocalServiceUtil.addTemplate(
331 userId, groupId, template.getClassNameId(), classPK, null,
332 template.getNameMap(), template.getDescriptionMap(),
333 template.getType(), template.getMode(), template.getLanguage(),
334 template.getScript(), template.isCacheable(),
335 template.isSmallImage(), template.getSmallImageURL(), smallFile,
336 serviceContext);
337
338 if (_log.isWarnEnabled()) {
339 _log.warn(
340 "A template with the key " + template.getTemplateKey() +
341 " already exists. The new generated key is " +
342 newTemplate.getTemplateKey());
343 }
344 }
345
346 return newTemplate;
347 }
348
349 protected static String getStructurePath(
350 PortletDataContext portletDataContext, DDMStructure structure) {
351
352 StringBundler sb = new StringBundler(4);
353
354 sb.append(
355 portletDataContext.getPortletPath(
356 PortletKeys.DYNAMIC_DATA_MAPPING));
357 sb.append("/structures/");
358 sb.append(structure.getStructureId());
359 sb.append(".xml");
360
361 return sb.toString();
362 }
363
364 protected static String getTemplatePath(
365 PortletDataContext portletDataContext, DDMTemplate template) {
366
367 StringBundler sb = new StringBundler(4);
368
369 sb.append(
370 portletDataContext.getPortletPath(
371 PortletKeys.DYNAMIC_DATA_MAPPING));
372 sb.append("/templates/");
373 sb.append(template.getTemplateId());
374 sb.append(".xml");
375
376 return sb.toString();
377 }
378
379 protected static String getTemplateSmallImagePath(
380 PortletDataContext portletDataContext, DDMTemplate template)
381 throws Exception {
382
383 StringBundler sb = new StringBundler(5);
384
385 sb.append(
386 portletDataContext.getPortletPath(
387 PortletKeys.DYNAMIC_DATA_MAPPING));
388 sb.append("/templates/thumbnail-");
389 sb.append(template.getTemplateId());
390 sb.append(StringPool.PERIOD);
391 sb.append(template.getSmallImageType());
392
393 return sb.toString();
394 }
395
396 protected static void prepareLanguagesForImport(DDMStructure structure)
397 throws PortalException {
398
399 Locale structureDefaultLocale = LocaleUtil.fromLanguageId(
400 structure.getDefaultLanguageId());
401
402 Locale[] structureAvailableLocales = LocaleUtil.fromLanguageIds(
403 structure.getAvailableLanguageIds());
404
405 Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
406 DDMStructure.class.getName(), structure.getPrimaryKey(),
407 structureDefaultLocale, structureAvailableLocales);
408
409 structure.prepareLocalizedFieldsForImport(defaultImportLocale);
410 }
411
412 @Override
413 protected PortletPreferences doDeleteData(
414 PortletDataContext portletDataContext, String portletId,
415 PortletPreferences portletPreferences)
416 throws Exception {
417
418 if (!portletDataContext.addPrimaryKey(
419 DDMPortletDataHandlerImpl.class, "deleteData")) {
420
421 DDMTemplateLocalServiceUtil.deleteTemplates(
422 portletDataContext.getScopeGroupId());
423
424 DDMStructureLocalServiceUtil.deleteStructures(
425 portletDataContext.getScopeGroupId());
426 }
427
428 return portletPreferences;
429 }
430
431 @Override
432 protected String doExportData(
433 PortletDataContext portletDataContext, String portletId,
434 PortletPreferences portletPreferences)
435 throws Exception {
436
437 portletDataContext.addPermissions(
438 "com.liferay.portlet.dynamicdatamapping",
439 portletDataContext.getScopeGroupId());
440
441 Document document = SAXReaderUtil.createDocument();
442
443 Element rootElement = document.addElement("ddm-data");
444
445 rootElement.addAttribute(
446 "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
447
448 Element structuresElement = rootElement.addElement("structures");
449
450 List<DDMStructure> ddmStructures = DDMStructureUtil.findByGroupId(
451 portletDataContext.getScopeGroupId());
452
453 for (DDMStructure structure : ddmStructures) {
454 if (portletDataContext.isWithinDateRange(
455 structure.getModifiedDate())) {
456
457 exportStructure(
458 portletDataContext, structuresElement, structure);
459 }
460 }
461
462 Element templatesElement = rootElement.addElement("templates");
463
464 if (portletDataContext.getBooleanParameter(_NAMESPACE, "templates")) {
465 List<DDMTemplate> templates = DDMTemplateUtil.findByG_C(
466 portletDataContext.getScopeGroupId(),
467 PortalUtil.getClassNameId(DDMStructure.class));
468
469 for (DDMTemplate template : templates) {
470 if (portletDataContext.isWithinDateRange(
471 template.getModifiedDate())) {
472
473 exportTemplate(
474 portletDataContext, templatesElement, template);
475 }
476 }
477 }
478
479 return document.formattedString();
480 }
481
482 @Override
483 protected PortletPreferences doImportData(
484 PortletDataContext portletDataContext, String portletId,
485 PortletPreferences portletPreferences, String data)
486 throws Exception {
487
488 portletDataContext.importPermissions(
489 "com.liferay.portlet.dynamicdatamapping",
490 portletDataContext.getSourceGroupId(),
491 portletDataContext.getScopeGroupId());
492
493 Document document = SAXReaderUtil.read(data);
494
495 Element rootElement = document.getRootElement();
496
497 Element structuresElement = rootElement.element("structures");
498
499 List<Element> structureElements = structuresElement.elements(
500 "structure");
501
502 for (Element structureElement : structureElements) {
503 importStructure(portletDataContext, structureElement);
504 }
505
506 if (portletDataContext.getBooleanParameter(_NAMESPACE, "templates")) {
507 Element templatesElement = rootElement.element("templates");
508
509 List<Element> templateElements = templatesElement.elements(
510 "template");
511
512 for (Element templateElement : templateElements) {
513 importTemplate(portletDataContext, templateElement);
514 }
515 }
516
517 return portletPreferences;
518 }
519
520 private static final boolean _ALWAYS_EXPORTABLE = true;
521
522 private static final boolean _DATA_LOCALIZED = true;
523
524 private static final String _NAMESPACE = "ddm";
525
526 private static Log _log = LogFactoryUtil.getLog(
527 DDMPortletDataHandlerImpl.class);
528
529 private static PortletDataHandlerBoolean _structures =
530 new PortletDataHandlerBoolean(_NAMESPACE, "structures", true, true);
531
532 private static PortletDataHandlerBoolean _templates =
533 new PortletDataHandlerBoolean(_NAMESPACE, "templates");
534
535 }