001
014
015 package com.liferay.portlet.blogs.lar;
016
017 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
018 import com.liferay.portal.kernel.lar.PortletDataContext;
019 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
020 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
021 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
022 import com.liferay.portal.kernel.util.StreamUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.kernel.workflow.WorkflowConstants;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.SAXReaderUtil;
031 import com.liferay.portal.model.Image;
032 import com.liferay.portal.service.ServiceContext;
033 import com.liferay.portal.service.persistence.ImageUtil;
034 import com.liferay.portal.util.PortletKeys;
035 import com.liferay.portal.util.PropsValues;
036 import com.liferay.portlet.blogs.model.BlogsEntry;
037 import com.liferay.portlet.blogs.service.BlogsEntryLocalServiceUtil;
038 import com.liferay.portlet.blogs.service.BlogsStatsUserLocalServiceUtil;
039 import com.liferay.portlet.blogs.service.persistence.BlogsEntryUtil;
040 import com.liferay.portlet.journal.lar.JournalPortletDataHandlerImpl;
041
042 import java.io.InputStream;
043
044 import java.util.Calendar;
045 import java.util.List;
046
047 import javax.portlet.PortletPreferences;
048
049
054 public class BlogsPortletDataHandlerImpl extends BasePortletDataHandler {
055
056 @Override
057 public PortletDataHandlerControl[] getExportControls() {
058 return new PortletDataHandlerControl[] {
059 _entries
060 };
061 }
062
063 @Override
064 public PortletDataHandlerControl[] getExportMetadataControls() {
065 return new PortletDataHandlerControl[] {
066 new PortletDataHandlerBoolean(
067 _NAMESPACE, "blog-entries", true, _metadataControls)
068 };
069 }
070
071 @Override
072 public PortletDataHandlerControl[] getImportControls() {
073 return new PortletDataHandlerControl[] {
074 _entries, _wordpress
075 };
076 }
077
078 @Override
079 public PortletDataHandlerControl[] getImportMetadataControls() {
080 return new PortletDataHandlerControl[] {
081 new PortletDataHandlerBoolean(
082 _NAMESPACE, "blog-entries", true, _metadataControls)
083 };
084 }
085
086 @Override
087 public boolean isAlwaysExportable() {
088 return _ALWAYS_EXPORTABLE;
089 }
090
091 @Override
092 public boolean isPublishToLiveByDefault() {
093 return PropsValues.BLOGS_PUBLISH_TO_LIVE_BY_DEFAULT;
094 }
095
096 @Override
097 protected PortletPreferences doDeleteData(
098 PortletDataContext portletDataContext, String portletId,
099 PortletPreferences portletPreferences)
100 throws Exception {
101
102 if (!portletDataContext.addPrimaryKey(
103 BlogsPortletDataHandlerImpl.class, "deleteData")) {
104
105 BlogsEntryLocalServiceUtil.deleteEntries(
106 portletDataContext.getScopeGroupId());
107
108 BlogsStatsUserLocalServiceUtil.deleteStatsUserByGroupId(
109 portletDataContext.getScopeGroupId());
110 }
111
112 return null;
113 }
114
115 @Override
116 protected String doExportData(
117 PortletDataContext portletDataContext, String portletId,
118 PortletPreferences portletPreferences)
119 throws Exception {
120
121 portletDataContext.addPermissions(
122 "com.liferay.portlet.blogs", portletDataContext.getScopeGroupId());
123
124 Document document = SAXReaderUtil.createDocument();
125
126 Element rootElement = document.addElement("blogs-data");
127
128 rootElement.addAttribute(
129 "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
130
131 Element entriesElement = rootElement.addElement("entries");
132
133 Element dlFileEntryTypesElement = entriesElement.addElement(
134 "dl-file-entry-types");
135 Element dlFoldersElement = entriesElement.addElement("dl-folders");
136 Element dlFileEntriesElement = entriesElement.addElement(
137 "dl-file-entries");
138 Element dlFileRanksElement = entriesElement.addElement("dl-file-ranks");
139 Element dlRepositoriesElement = entriesElement.addElement(
140 "dl-repositories");
141 Element dlRepositoryEntriesElement = entriesElement.addElement(
142 "dl-repository-entries");
143
144 List<BlogsEntry> entries = BlogsEntryUtil.findByGroupId(
145 portletDataContext.getScopeGroupId());
146
147 for (BlogsEntry entry : entries) {
148 exportEntry(
149 portletDataContext, entriesElement, dlFileEntryTypesElement,
150 dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
151 dlRepositoriesElement, dlRepositoryEntriesElement, entry);
152 }
153
154 return document.formattedString();
155 }
156
157 @Override
158 protected PortletPreferences doImportData(
159 PortletDataContext portletDataContext, String portletId,
160 PortletPreferences portletPreferences, String data)
161 throws Exception {
162
163 portletDataContext.importPermissions(
164 "com.liferay.portlet.blogs", portletDataContext.getSourceGroupId(),
165 portletDataContext.getScopeGroupId());
166
167 Document document = SAXReaderUtil.read(data);
168
169 Element rootElement = document.getRootElement();
170
171 Element entriesElement = rootElement.element("entries");
172
173 if (entriesElement != null) {
174 JournalPortletDataHandlerImpl.importReferencedData(
175 portletDataContext, entriesElement);
176 }
177 else {
178 entriesElement = rootElement;
179 }
180
181 for (Element entryElement : entriesElement.elements("entry")) {
182 String path = entryElement.attributeValue("path");
183
184 if (!portletDataContext.isPathNotProcessed(path)) {
185 continue;
186 }
187
188 BlogsEntry entry =
189 (BlogsEntry)portletDataContext.getZipEntryAsObject(path);
190
191 importEntry(portletDataContext, entryElement, entry);
192 }
193
194 if (portletDataContext.getBooleanParameter(_NAMESPACE, "wordpress")) {
195 WordPressImporter.importData(portletDataContext);
196 }
197
198 return null;
199 }
200
201 protected void exportEntry(
202 PortletDataContext portletDataContext, Element entriesElement,
203 Element dlFileEntryTypesElement, Element dlFoldersElement,
204 Element dlFileEntriesElement, Element dlFileRanksElement,
205 Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
206 BlogsEntry entry)
207 throws Exception {
208
209 if (!portletDataContext.isWithinDateRange(entry.getModifiedDate())) {
210 return;
211 }
212
213 if (!entry.isApproved() && !entry.isInTrash()) {
214 return;
215 }
216
217 String path = getEntryPath(portletDataContext, entry);
218
219 if (!portletDataContext.isPathNotProcessed(path)) {
220 return;
221 }
222
223
224
225
226 entry = (BlogsEntry)entry.clone();
227
228 Element entryElement = (Element)entriesElement.selectSingleNode(
229 "
230
231 if (entryElement == null) {
232 entryElement = entriesElement.addElement("entry");
233 }
234
235 String content = JournalPortletDataHandlerImpl.exportReferencedContent(
236 portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
237 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
238 dlRepositoryEntriesElement, entryElement, entry.getContent());
239
240 entry.setContent(content);
241
242 String imagePath = getEntryImagePath(portletDataContext, entry);
243
244 entryElement.addAttribute("image-path", imagePath);
245
246 Image smallImage = ImageUtil.fetchByPrimaryKey(entry.getSmallImageId());
247
248 if (entry.isSmallImage() && (smallImage != null)) {
249 String smallImagePath = getEntrySmallImagePath(
250 portletDataContext, entry);
251
252 entryElement.addAttribute("small-image-path", smallImagePath);
253
254 entry.setSmallImageType(smallImage.getType());
255
256 portletDataContext.addZipEntry(
257 smallImagePath, smallImage.getTextObj());
258 }
259
260 portletDataContext.addClassedModel(
261 entryElement, path, entry, _NAMESPACE);
262 }
263
264 protected String getEntryImagePath(
265 PortletDataContext portletDataContext, BlogsEntry entry)
266 throws Exception {
267
268 StringBundler sb = new StringBundler(4);
269
270 sb.append(portletDataContext.getPortletPath(PortletKeys.BLOGS));
271 sb.append("/entry/");
272 sb.append(entry.getUuid());
273 sb.append(StringPool.SLASH);
274
275 return sb.toString();
276 }
277
278 protected String getEntryPath(
279 PortletDataContext portletDataContext, BlogsEntry entry) {
280
281 StringBundler sb = new StringBundler(4);
282
283 sb.append(portletDataContext.getPortletPath(PortletKeys.BLOGS));
284 sb.append("/entries/");
285 sb.append(entry.getEntryId());
286 sb.append(".xml");
287
288 return sb.toString();
289 }
290
291 protected String getEntrySmallImagePath(
292 PortletDataContext portletDataContext, BlogsEntry entry)
293 throws Exception {
294
295 StringBundler sb = new StringBundler(6);
296
297 sb.append(portletDataContext.getPortletPath(PortletKeys.BLOGS));
298 sb.append("/entries/");
299 sb.append(entry.getUuid());
300 sb.append("/thumbnail");
301 sb.append(StringPool.PERIOD);
302 sb.append(entry.getSmallImageType());
303
304 return sb.toString();
305 }
306
307 protected void importEntry(
308 PortletDataContext portletDataContext, Element entryElement,
309 BlogsEntry entry)
310 throws Exception {
311
312 long userId = portletDataContext.getUserId(entry.getUserUuid());
313
314 String content = JournalPortletDataHandlerImpl.importReferencedContent(
315 portletDataContext, entryElement, entry.getContent());
316
317 entry.setContent(content);
318
319 Calendar displayDateCal = CalendarFactoryUtil.getCalendar();
320
321 displayDateCal.setTime(entry.getDisplayDate());
322
323 int displayDateMonth = displayDateCal.get(Calendar.MONTH);
324 int displayDateDay = displayDateCal.get(Calendar.DATE);
325 int displayDateYear = displayDateCal.get(Calendar.YEAR);
326 int displayDateHour = displayDateCal.get(Calendar.HOUR);
327 int displayDateMinute = displayDateCal.get(Calendar.MINUTE);
328
329 if (displayDateCal.get(Calendar.AM_PM) == Calendar.PM) {
330 displayDateHour += 12;
331 }
332
333 boolean allowPingbacks = entry.isAllowPingbacks();
334 boolean allowTrackbacks = entry.isAllowTrackbacks();
335 String[] trackbacks = StringUtil.split(entry.getTrackbacks());
336 int status = entry.getStatus();
337
338 String smallImageFileName = null;
339 InputStream smallImageInputStream = null;
340
341 try {
342 String smallImagePath = entryElement.attributeValue(
343 "small-image-path");
344
345 if (entry.isSmallImage() && Validator.isNotNull(smallImagePath)) {
346 smallImageFileName = String.valueOf(
347 entry.getSmallImageId()).concat(
348 StringPool.PERIOD).concat(entry.getSmallImageType());
349 smallImageInputStream =
350 portletDataContext.getZipEntryAsInputStream(smallImagePath);
351 }
352
353 ServiceContext serviceContext =
354 portletDataContext.createServiceContext(
355 entryElement, entry, _NAMESPACE);
356
357 if ((status != WorkflowConstants.STATUS_APPROVED) &&
358 (status != WorkflowConstants.STATUS_IN_TRASH)) {
359
360 serviceContext.setWorkflowAction(
361 WorkflowConstants.ACTION_SAVE_DRAFT);
362 }
363
364 BlogsEntry importedEntry = null;
365
366 if (portletDataContext.isDataStrategyMirror()) {
367 serviceContext.setAttribute("urlTitle", entry.getUrlTitle());
368
369 BlogsEntry existingEntry = BlogsEntryUtil.fetchByUUID_G(
370 entry.getUuid(), portletDataContext.getScopeGroupId());
371
372 if (existingEntry == null) {
373 serviceContext.setUuid(entry.getUuid());
374
375 importedEntry = BlogsEntryLocalServiceUtil.addEntry(
376 userId, entry.getTitle(), entry.getDescription(),
377 entry.getContent(), displayDateMonth, displayDateDay,
378 displayDateYear, displayDateHour, displayDateMinute,
379 allowPingbacks, allowTrackbacks, trackbacks,
380 entry.isSmallImage(), entry.getSmallImageURL(),
381 smallImageFileName, smallImageInputStream,
382 serviceContext);
383
384 if (status == WorkflowConstants.STATUS_IN_TRASH) {
385 importedEntry =
386 BlogsEntryLocalServiceUtil.moveEntryToTrash(
387 userId, importedEntry);
388 }
389 }
390 else {
391 importedEntry = BlogsEntryLocalServiceUtil.updateEntry(
392 userId, existingEntry.getEntryId(), entry.getTitle(),
393 entry.getDescription(), entry.getContent(),
394 displayDateMonth, displayDateDay, displayDateYear,
395 displayDateHour, displayDateMinute, allowPingbacks,
396 allowTrackbacks, trackbacks, entry.getSmallImage(),
397 entry.getSmallImageURL(), smallImageFileName,
398 smallImageInputStream, serviceContext);
399 }
400 }
401 else {
402 importedEntry = BlogsEntryLocalServiceUtil.addEntry(
403 userId, entry.getTitle(), entry.getDescription(),
404 entry.getContent(), displayDateMonth, displayDateDay,
405 displayDateYear, displayDateHour, displayDateMinute,
406 allowPingbacks, allowTrackbacks, trackbacks,
407 entry.getSmallImage(), entry.getSmallImageURL(),
408 smallImageFileName, smallImageInputStream, serviceContext);
409 }
410
411 portletDataContext.importClassedModel(
412 entry, importedEntry, _NAMESPACE);
413 }
414 finally {
415 StreamUtil.cleanUp(smallImageInputStream);
416 }
417
418 }
419
420 private static final boolean _ALWAYS_EXPORTABLE = true;
421
422 private static final String _NAMESPACE = "blogs";
423
424 private static PortletDataHandlerBoolean _entries =
425 new PortletDataHandlerBoolean(_NAMESPACE, "entries", true, true);
426
427 private static PortletDataHandlerControl[] _metadataControls =
428 new PortletDataHandlerControl[] {
429 new PortletDataHandlerBoolean(_NAMESPACE, "categories"),
430 new PortletDataHandlerBoolean(_NAMESPACE, "comments"),
431 new PortletDataHandlerBoolean(_NAMESPACE, "ratings"),
432 new PortletDataHandlerBoolean(_NAMESPACE, "tags")
433 };
434
435 private static PortletDataHandlerBoolean _wordpress =
436 new PortletDataHandlerBoolean(_NAMESPACE, "wordpress");
437
438 }