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