1
14
15 package com.liferay.portlet.blogs.lar;
16
17 import com.liferay.portal.PortalException;
18 import com.liferay.portal.SystemException;
19 import com.liferay.portal.kernel.log.Log;
20 import com.liferay.portal.kernel.log.LogFactoryUtil;
21 import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
22 import com.liferay.portal.kernel.util.GetterUtil;
23 import com.liferay.portal.kernel.util.StringPool;
24 import com.liferay.portal.kernel.util.TimeZoneUtil;
25 import com.liferay.portal.kernel.util.Validator;
26 import com.liferay.portal.kernel.xml.Document;
27 import com.liferay.portal.kernel.xml.DocumentException;
28 import com.liferay.portal.kernel.xml.Element;
29 import com.liferay.portal.kernel.xml.Namespace;
30 import com.liferay.portal.kernel.xml.Node;
31 import com.liferay.portal.kernel.xml.SAXReaderUtil;
32 import com.liferay.portal.lar.PortletDataContext;
33 import com.liferay.portal.model.User;
34 import com.liferay.portal.service.ServiceContext;
35 import com.liferay.portal.service.UserLocalServiceUtil;
36 import com.liferay.portal.service.persistence.UserUtil;
37 import com.liferay.portal.util.PortletKeys;
38 import com.liferay.portlet.blogs.model.BlogsEntry;
39 import com.liferay.portlet.blogs.service.BlogsEntryLocalServiceUtil;
40 import com.liferay.portlet.messageboards.model.MBMessage;
41 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
42 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
43
44 import java.text.DateFormat;
45 import java.text.ParseException;
46
47 import java.util.Calendar;
48 import java.util.Date;
49 import java.util.HashMap;
50 import java.util.List;
51 import java.util.Map;
52
53
58 public class WordPressImporter {
59
60 public static void importData(PortletDataContext context)
61 throws PortalException, SystemException {
62
63 Map<String, Long> userMap = getWordPressUserMap(context);
64
65 String path = getWordPressPath(context, _EXPORT_FILE);
66
67 String fileData = context.getZipEntryAsString(path);
68
69 if (Validator.isNull(fileData)) {
70 return;
71 }
72
73 Document wordPressDoc = null;
74
75 try {
76 wordPressDoc = SAXReaderUtil.read(fileData);
77 }
78 catch (DocumentException de) {
79 _log.error("Reading " + path, de);
80
81 return;
82 }
83
84 User defaultUser = UserLocalServiceUtil.getDefaultUser(
85 context.getCompanyId());
86
87 Element root = wordPressDoc.getRootElement();
88
89 List<Element> entryEls = root.element("channel").elements("item");
90
91 DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
92 _DATE_FORMAT);
93
94 dateFormat.setTimeZone(TimeZoneUtil.getTimeZone(StringPool.UTC));
95
96 for (Element entryEl : entryEls) {
97 importEntry(context, defaultUser, userMap, dateFormat, entryEl);
98 }
99 }
100
101 protected static String getWordPressPath(
102 PortletDataContext context, String fileName) {
103
104 return context.getSourcePortletPath(PortletKeys.BLOGS).concat(
105 StringPool.SLASH).concat(fileName);
106 }
107
108 protected static Map<String, Long> getWordPressUserMap(
109 PortletDataContext context) {
110
111 Map<String, Long> userMap = new HashMap<String, Long>();
112
113 String path = getWordPressPath(context, _USER_MAP_FILE);
114
115 String fileData = context.getZipEntryAsString(path);
116
117 if (Validator.isNull(fileData)) {
118 return userMap;
119 }
120
121 Document doc = null;
122
123 try {
124 doc = SAXReaderUtil.read(fileData);
125 }
126 catch(DocumentException de) {
127 _log.error(de.getMessage(), de);
128
129 return userMap;
130 }
131
132 Element root = doc.getRootElement();
133
134 List<Element> userEls = root.elements("wordpress-user");
135
136 for (Element userEl : userEls) {
137 try {
138 User user = UserUtil.findByC_EA(
139 context.getCompanyId(),
140 userEl.attributeValue("email-address"));
141
142 userMap.put(userEl.getTextTrim(), user.getUserId());
143 }
144 catch (Exception e) {
145 if (_log.isDebugEnabled()) {
146 _log.debug(
147 "User for {" + context.getCompanyId() + ", " +
148 userEl.attributeValue("email-address") + "}", e);
149 }
150 }
151 }
152
153 return userMap;
154 }
155
156 protected static void importComment(
157 PortletDataContext context, User defaultUser,
158 MBMessageDisplay messageDisplay, Map<Long, Long> messageIdMap,
159 BlogsEntry entry, Element commentEl)
160 throws PortalException, SystemException {
161
162 long commentId = GetterUtil.getLong(
163 commentEl.elementTextTrim(
164 SAXReaderUtil.createQName("comment_id", _NS_WP)));
165
166 String commentContent = commentEl.elementTextTrim(
167 SAXReaderUtil.createQName("comment_content", _NS_WP));
168
169 if (Validator.isNull(commentContent)) {
170 return;
171 }
172
173 String commentAuthor = commentEl.elementTextTrim(
174 SAXReaderUtil.createQName("comment_author", _NS_WP));
175
176 commentAuthor = commentAuthor.substring(
177 0, Math.min(75, commentAuthor.length()));
178
179 long commentParentId = GetterUtil.getLong(
180 commentEl.elementTextTrim(
181 SAXReaderUtil.createQName("comment_parent", _NS_WP)));
182
183 if (commentParentId == 0) {
184 commentParentId =
185 messageDisplay.getMessage().getMessageId();
186 }
187 else {
188 commentParentId = messageIdMap.get(commentParentId);
189 }
190
191 ServiceContext serviceContext = new ServiceContext();
192
193 serviceContext.setAddCommunityPermissions(true);
194 serviceContext.setAddGuestPermissions(true);
195 serviceContext.setScopeGroupId(context.getGroupId());
196
197 MBMessage message = MBMessageLocalServiceUtil.addDiscussionMessage(
198 defaultUser.getUserId(), commentAuthor, BlogsEntry.class.getName(),
199 entry.getEntryId(), messageDisplay.getThread().getThreadId(),
200 commentParentId, null, commentContent, serviceContext);
201
202 messageIdMap.put(commentId, message.getMessageId());
203 }
204
205 protected static void importEntry(
206 PortletDataContext context, User defaultUser,
207 Map<String, Long> userMap, DateFormat dateFormat, Element entryEl)
208 throws PortalException, SystemException {
209
210 long userId = context.getUserId(null);
211
212 String creator = entryEl.elementText(
213 SAXReaderUtil.createQName("creator", _NS_DC));
214
215 if (userMap.containsKey(creator)) {
216 userId = userMap.get(creator);
217 }
218
219 String title = entryEl.elementTextTrim("title");
220
221 if (Validator.isNull(title)) {
222 title = entryEl.elementTextTrim(
223 SAXReaderUtil.createQName("post_name", _NS_WP));
224 }
225
226 String content = entryEl.elementText(
227 SAXReaderUtil.createQName("encoded", _NS_CONTENT));
228
229 content = content.replaceAll("\\n", "\n<br />");
230
231
233 if (Validator.isNull(content)) {
234 content = "<br />";
235 }
236
237 String dateText = entryEl.elementTextTrim(
238 SAXReaderUtil.createQName("post_date_gmt", _NS_WP));
239
240 Date postDate = new Date();
241
242 try {
243 postDate = dateFormat.parse(dateText);
244 }
245 catch (ParseException pe) {
246 _log.warn("Parse " + dateText, pe);
247 }
248
249 Calendar cal = Calendar.getInstance();
250
251 cal.setTime(postDate);
252
253 int displayDateMonth = cal.get(Calendar.MONTH);
254 int displayDateDay = cal.get(Calendar.DAY_OF_MONTH);
255 int displayDateYear = cal.get(Calendar.YEAR);
256 int displayDateHour = cal.get(Calendar.HOUR_OF_DAY);
257 int displayDateMinute = cal.get(Calendar.MINUTE);
258
259 String statusText = entryEl.elementTextTrim(
260 SAXReaderUtil.createQName("status", _NS_WP));
261
262 boolean draft = statusText.equalsIgnoreCase("draft");
263
264 String pingStatusText = entryEl.elementTextTrim(
265 SAXReaderUtil.createQName("ping_status", _NS_WP));
266
267 boolean allowTrackbacks = pingStatusText.equalsIgnoreCase("open");
268
269 String[] tagsEntries = null;
270
271 String categoryText = entryEl.elementTextTrim("category");
272
273 if (Validator.isNotNull(categoryText)) {
274 tagsEntries = new String[] {categoryText};
275 }
276
277 ServiceContext serviceContext = new ServiceContext();
278
279 serviceContext.setAddCommunityPermissions(true);
280 serviceContext.setAddGuestPermissions(true);
281 serviceContext.setScopeGroupId(context.getGroupId());
282 serviceContext.setTagsEntries(tagsEntries);
283
284 BlogsEntry entry = null;
285
286 try {
287 entry = BlogsEntryLocalServiceUtil.addEntry(
288 userId, title, content, displayDateMonth, displayDateDay,
289 displayDateYear, displayDateHour, displayDateMinute, draft,
290 allowTrackbacks, null, serviceContext);
291 }
292 catch (Exception e) {
293 _log.error("Add entry " + title, e);
294
295 return;
296 }
297
298 MBMessageDisplay messageDisplay =
299 MBMessageLocalServiceUtil.getDiscussionMessageDisplay(
300 userId, BlogsEntry.class.getName(), entry.getEntryId());
301
302 Map<Long, Long> messageIdMap = new HashMap<Long, Long>();
303
304 List<Node> commentNodes = entryEl.selectNodes(
305 "wp:comment", "wp:comment_parent/text()");
306
307 for (Node commentNode : commentNodes) {
308 Element commentEl = (Element)commentNode;
309
310 importComment(
311 context, defaultUser, messageDisplay, messageIdMap, entry,
312 commentEl);
313 }
314 }
315
316 private static final String _DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
317
318 private static final String _EXPORT_FILE = "wordpress.xml";
319
320 private static final Namespace _NS_CONTENT = SAXReaderUtil.createNamespace(
321 "content", "http://purl.org/rss/1.0/modules/content/");
322
323 private static final Namespace _NS_DC = SAXReaderUtil.createNamespace(
324 "dc", "http://purl.org/dc/elements/1.1/");
325
326 private static final Namespace _NS_WP = SAXReaderUtil.createNamespace(
327 "wp", "http://wordpress.org/export/1.0/");
328
329 private static final String _USER_MAP_FILE = "wordpress-user-map.xml";
330
331 private static Log _log = LogFactoryUtil.getLog(WordPressImporter.class);
332
333 }