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