1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.lar;
24  
25  import com.liferay.portal.LARFileException;
26  import com.liferay.portal.LARTypeException;
27  import com.liferay.portal.LayoutImportException;
28  import com.liferay.portal.NoSuchPortletPreferencesException;
29  import com.liferay.portal.PortalException;
30  import com.liferay.portal.PortletIdException;
31  import com.liferay.portal.SystemException;
32  import com.liferay.portal.kernel.log.Log;
33  import com.liferay.portal.kernel.log.LogFactoryUtil;
34  import com.liferay.portal.kernel.util.GetterUtil;
35  import com.liferay.portal.kernel.util.ObjectValuePair;
36  import com.liferay.portal.kernel.util.PortletClassInvoker;
37  import com.liferay.portal.kernel.util.ReleaseInfo;
38  import com.liferay.portal.kernel.util.StringUtil;
39  import com.liferay.portal.kernel.util.Validator;
40  import com.liferay.portal.kernel.xml.Document;
41  import com.liferay.portal.kernel.xml.DocumentException;
42  import com.liferay.portal.kernel.xml.Element;
43  import com.liferay.portal.kernel.xml.SAXReaderUtil;
44  import com.liferay.portal.kernel.zip.ZipReader;
45  import com.liferay.portal.model.Group;
46  import com.liferay.portal.model.Layout;
47  import com.liferay.portal.model.Portlet;
48  import com.liferay.portal.model.PortletConstants;
49  import com.liferay.portal.model.PortletItem;
50  import com.liferay.portal.model.PortletPreferences;
51  import com.liferay.portal.model.User;
52  import com.liferay.portal.service.GroupLocalServiceUtil;
53  import com.liferay.portal.service.LayoutLocalServiceUtil;
54  import com.liferay.portal.service.PortletItemLocalServiceUtil;
55  import com.liferay.portal.service.PortletLocalServiceUtil;
56  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
57  import com.liferay.portal.service.UserLocalServiceUtil;
58  import com.liferay.portal.service.persistence.PortletPreferencesUtil;
59  import com.liferay.portal.service.persistence.UserUtil;
60  import com.liferay.portal.util.PortletKeys;
61  import com.liferay.portlet.PortletPreferencesFactoryUtil;
62  import com.liferay.portlet.PortletPreferencesImpl;
63  import com.liferay.portlet.PortletPreferencesSerializer;
64  import com.liferay.portlet.messageboards.model.MBMessage;
65  import com.liferay.portlet.ratings.model.RatingsEntry;
66  import com.liferay.util.MapUtil;
67  
68  import java.io.InputStream;
69  
70  import java.util.ArrayList;
71  import java.util.HashSet;
72  import java.util.List;
73  import java.util.Map;
74  
75  import org.apache.commons.lang.time.StopWatch;
76  
77  /**
78   * <a href="PortletImporter.java.html"><b><i>View Source</i></b></a>
79   *
80   * @author Brian Wing Shun Chan
81   * @author Joel Kozikowski
82   * @author Charles May
83   * @author Raymond Augé
84   * @author Jorge Ferrer
85   * @author Bruno Farache
86   *
87   */
88  public class PortletImporter {
89  
90      public void importPortletInfo(
91              long userId, long plid, long groupId, String portletId,
92              Map<String, String[]> parameterMap, InputStream is)
93          throws PortalException, SystemException {
94  
95          boolean deletePortletData = MapUtil.getBoolean(
96              parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
97          boolean importPortletData = MapUtil.getBoolean(
98              parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
99          boolean importPortletArchivedSetups = MapUtil.getBoolean(
100             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
101         boolean importPortletSetup = MapUtil.getBoolean(
102             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
103         boolean importUserPreferences = MapUtil.getBoolean(
104             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
105         String userIdStrategy = MapUtil.getString(
106             parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
107 
108         StopWatch stopWatch = null;
109 
110         if (_log.isInfoEnabled()) {
111             stopWatch = new StopWatch();
112 
113             stopWatch.start();
114         }
115 
116         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
117 
118         long companyId = layout.getCompanyId();
119 
120         User user = UserUtil.findByPrimaryKey(userId);
121 
122         UserIdStrategy strategy = getUserIdStrategy(user, userIdStrategy);
123 
124         ZipReader zipReader = new ZipReader(is);
125 
126         PortletDataContext context = new PortletDataContextImpl(
127             companyId, groupId, parameterMap, new HashSet<String>(),
128             strategy, zipReader);
129 
130         context.setPlid(plid);
131         context.setPrivateLayout(layout.isPrivateLayout());
132 
133         // Zip
134 
135         Element root = null;
136 
137         // Manifest
138 
139         String xml = context.getZipEntryAsString("/manifest.xml");
140 
141         try {
142             Document doc = SAXReaderUtil.read(xml);
143 
144             root = doc.getRootElement();
145         }
146         catch (Exception e) {
147             throw new LARFileException(
148                 "Cannot locate a manifest in this LAR file.");
149         }
150 
151         // Build compatibility
152 
153         Element header = root.element("header");
154 
155         int buildNumber = ReleaseInfo.getBuildNumber();
156 
157         int importBuildNumber = GetterUtil.getInteger(
158             header.attributeValue("build-number"));
159 
160         if (buildNumber != importBuildNumber) {
161             throw new LayoutImportException(
162                 "LAR build number " + importBuildNumber + " does not match " +
163                     "portal build number " + buildNumber);
164         }
165 
166         // Type compatibility
167 
168         String type = header.attributeValue("type");
169 
170         if (!type.equals("portlet")) {
171             throw new LARTypeException(
172                 "Invalid type of LAR file (" + type + ")");
173         }
174 
175         // Portlet compatibility
176 
177         String rootPortletId = header.attributeValue("root-portlet-id");
178 
179         if (!PortletConstants.getRootPortletId(portletId).equals(
180                 rootPortletId)) {
181 
182             throw new PortletIdException("Invalid portlet id " + rootPortletId);
183         }
184 
185         // Import GroupId
186 
187         long sourceGroupId = GetterUtil.getLong(
188             header.attributeValue("group-id"));
189 
190         context.setSourceGroupId(sourceGroupId);
191 
192         // Read categories, comments, ratings, and tags to make them available
193         // to the data handlers through the context
194 
195         readCategories(context, root);
196         readComments(context, root);
197         readRatings(context, root);
198         readTags(context, root);
199 
200         // Delete portlet data
201 
202         if (_log.isDebugEnabled()) {
203             _log.debug("Deleting portlet data");
204         }
205 
206         if (deletePortletData) {
207             deletePortletData(context, portletId, plid);
208         }
209 
210         Element portletRefEl = root.element("portlet");
211         Element portletEl = null;
212 
213         try {
214             Document portletDoc = SAXReaderUtil.read(
215                 context.getZipEntryAsString(
216                     portletRefEl.attributeValue("path")));
217 
218             portletEl = portletDoc.getRootElement();
219         }
220         catch (DocumentException de) {
221             throw new SystemException(de);
222         }
223 
224         // Portlet preferences
225 
226         importPortletPreferences(
227             context, layout.getCompanyId(), groupId, layout, portletId,
228             portletEl, importPortletSetup, importPortletArchivedSetups,
229             importUserPreferences, true);
230 
231         // Portlet data
232 
233         if (_log.isDebugEnabled()) {
234             _log.debug("Importing portlet data");
235         }
236 
237         if (importPortletData) {
238             importPortletData(
239                 context, portletId, plid, portletEl.element("portlet-data"));
240         }
241 
242         if (_log.isInfoEnabled()) {
243             _log.info(
244                 "Importing portlet data takes " + stopWatch.getTime() + " ms");
245         }
246     }
247 
248     protected void deletePortletData(
249             PortletDataContext context, String portletId, long plid)
250         throws SystemException {
251 
252         long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
253         int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
254 
255         PortletPreferences portletPreferences = null;
256 
257         try {
258             portletPreferences = PortletPreferencesUtil.findByO_O_P_P(
259                 ownerId, ownerType, plid, portletId);
260         }
261         catch (NoSuchPortletPreferencesException nsppe) {
262             portletPreferences =
263                 new com.liferay.portal.model.impl.PortletPreferencesImpl();
264         }
265 
266         String xml = deletePortletData(
267             context, portletId, portletPreferences);
268 
269         if (xml != null) {
270             PortletPreferencesLocalServiceUtil.updatePreferences(
271                 ownerId, ownerType, plid, portletId, xml);
272         }
273     }
274 
275     protected String deletePortletData(
276             PortletDataContext context, String portletId,
277             PortletPreferences portletPreferences)
278         throws SystemException {
279 
280         Portlet portlet = PortletLocalServiceUtil.getPortletById(
281             context.getCompanyId(), portletId);
282 
283         if (portlet == null) {
284             if (_log.isDebugEnabled()) {
285                 _log.debug(
286                     "Do not delete portlet data for " + portletId +
287                         " because the portlet does not exist");
288             }
289 
290             return null;
291         }
292 
293         String portletDataHandlerClass =
294             portlet.getPortletDataHandlerClass();
295 
296         if (Validator.isNull(portletDataHandlerClass)) {
297             if (_log.isDebugEnabled()) {
298                 _log.debug(
299                     "Do not delete portlet data for " + portletId +
300                         " because the portlet does not have a " +
301                             "PortletDataHandler");
302             }
303 
304             return null;
305         }
306 
307         if (_log.isDebugEnabled()) {
308             _log.debug("Deleting data for " + portletId);
309         }
310 
311         PortletPreferencesImpl preferencesImpl =
312             (PortletPreferencesImpl)PortletPreferencesSerializer.fromDefaultXML(
313                 portletPreferences.getPreferences());
314 
315         try {
316             preferencesImpl =
317                 (PortletPreferencesImpl)PortletClassInvoker.invoke(
318                     portletId, portletDataHandlerClass, "deleteData", context,
319                     portletId, preferencesImpl);
320         }
321         catch (Exception e) {
322             throw new SystemException(e);
323         }
324         finally {
325             context.setGroupId(context.getScopeGroupId());
326         }
327 
328         if (preferencesImpl == null) {
329             return null;
330         }
331 
332         return PortletPreferencesSerializer.toXML(preferencesImpl);
333     }
334 
335     protected UserIdStrategy getUserIdStrategy(
336         User user, String userIdStrategy) {
337 
338         if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
339             return new AlwaysCurrentUserIdStrategy(user);
340         }
341 
342         return new CurrentUserIdStrategy(user);
343     }
344 
345     protected void importPortletData(
346             PortletDataContext context, String portletId, long plid,
347             Element portletDataRefEl)
348         throws SystemException {
349 
350         long ownerId = PortletKeys. PREFS_OWNER_ID_DEFAULT;
351         int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
352 
353         PortletPreferences portletPreferences = null;
354 
355         try {
356             portletPreferences = PortletPreferencesUtil.findByO_O_P_P(
357                 ownerId, ownerType, plid, portletId);
358         }
359         catch (NoSuchPortletPreferencesException nsppe) {
360             portletPreferences =
361                 new com.liferay.portal.model.impl.PortletPreferencesImpl();
362         }
363 
364         String xml = importPortletData(
365             context, portletId, portletPreferences, portletDataRefEl);
366 
367         if (xml != null) {
368             PortletPreferencesLocalServiceUtil.updatePreferences(
369                 ownerId, ownerType, plid, portletId, xml);
370         }
371     }
372 
373     protected String importPortletData(
374             PortletDataContext context, String portletId,
375             PortletPreferences portletPreferences, Element portletDataRefEl)
376         throws SystemException {
377 
378         Portlet portlet = PortletLocalServiceUtil.getPortletById(
379             context.getCompanyId(), portletId);
380 
381         if (portlet == null) {
382             if (_log.isDebugEnabled()) {
383                 _log.debug(
384                     "Do not import portlet data for " + portletId +
385                         " because the portlet does not exist");
386             }
387 
388             return null;
389         }
390 
391         String portletDataHandlerClass =
392             portlet.getPortletDataHandlerClass();
393 
394         if (Validator.isNull(portletDataHandlerClass)) {
395             if (_log.isDebugEnabled()) {
396                 _log.debug(
397                     "Do not import portlet data for " + portletId +
398                         " because the portlet does not have a " +
399                             "PortletDataHandler");
400             }
401 
402             return null;
403         }
404 
405         if (_log.isDebugEnabled()) {
406             _log.debug("Importing data for " + portletId);
407         }
408 
409         // Layout scope
410 
411         long groupId = context.getGroupId();
412 
413         long scopeLayoutId = context.getScopeLayoutId();
414 
415         if (scopeLayoutId == 0) {
416             scopeLayoutId = GetterUtil.getLong(
417                 portletDataRefEl.getParent().attributeValue("scope-layout-id"));
418         }
419 
420         if (scopeLayoutId > 0) {
421             try {
422                 Layout scopeLayout = LayoutLocalServiceUtil.getLayout(
423                     context.getGroupId(), context.isPrivateLayout(),
424                     scopeLayoutId);
425 
426                 Group scopeGroup = null;
427 
428                 if (scopeLayout.hasScopeGroup()) {
429                     scopeGroup = scopeLayout.getScopeGroup();
430                 }
431                 else {
432                     String name = String.valueOf(scopeLayout.getPlid());
433 
434                     scopeGroup = GroupLocalServiceUtil.addGroup(
435                         context.getUserId(null), Layout.class.getName(),
436                         scopeLayout.getPlid(), name, null, 0, null, true);
437                 }
438 
439                 context.setGroupId(scopeGroup.getGroupId());
440             }
441             catch (PortalException pe) {
442             }
443         }
444 
445         PortletPreferencesImpl preferencesImpl = null;
446 
447         if (portletPreferences != null) {
448             preferencesImpl = (PortletPreferencesImpl)
449                 PortletPreferencesSerializer.fromDefaultXML(
450                     portletPreferences.getPreferences());
451         }
452 
453         String portletData = context.getZipEntryAsString(
454             portletDataRefEl.attributeValue("path"));
455 
456         try {
457             preferencesImpl =
458                 (PortletPreferencesImpl)PortletClassInvoker.invoke(
459                     portletId, portletDataHandlerClass, "importData", context,
460                     portletId, preferencesImpl, portletData);
461         }
462         catch (Exception e) {
463             throw new SystemException(e);
464         }
465         finally {
466             context.setGroupId(groupId);
467         }
468 
469         if (preferencesImpl == null) {
470             return null;
471         }
472 
473         return PortletPreferencesSerializer.toXML(preferencesImpl);
474     }
475 
476     protected void importPortletPreferences(
477             PortletDataContext context, long companyId, long groupId,
478             Layout layout, String portletId, Element parentEl,
479             boolean importPortletSetup, boolean importPortletArchivedSetups,
480             boolean importUserPreferences, boolean preserveScopeLayoutId)
481         throws PortalException, SystemException {
482 
483         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
484         long plid = 0;
485         long scopeLayoutId = 0;
486 
487         if (layout != null) {
488             plid = layout.getPlid();
489 
490             if (preserveScopeLayoutId && (portletId != null)) {
491                 javax.portlet.PortletPreferences jxPreferences =
492                     PortletPreferencesFactoryUtil.getLayoutPortletSetup(
493                         layout, portletId);
494 
495                 scopeLayoutId = GetterUtil.getLong(
496                     jxPreferences.getValue("lfr-scope-layout-id", null));
497 
498                 context.setScopeLayoutId(scopeLayoutId);
499             }
500         }
501 
502         List<Element> preferencesEls = parentEl.elements("portlet-preferences");
503 
504         for (Element preferencesEl : preferencesEls) {
505             String path = preferencesEl.attributeValue("path");
506 
507             if (context.isPathNotProcessed(path)) {
508                 Element el = null;
509                 String xml = null;
510 
511                 try {
512                     xml = context.getZipEntryAsString(path);
513 
514                     Document preferencesDoc = SAXReaderUtil.read(xml);
515 
516                     el = preferencesDoc.getRootElement();
517                 }
518                 catch (DocumentException de) {
519                     throw new SystemException(de);
520                 }
521 
522                 long ownerId = GetterUtil.getLong(
523                     el.attributeValue("owner-id"));
524                 int ownerType = GetterUtil.getInteger(
525                     el.attributeValue("owner-type"));
526 
527                 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
528                     continue;
529                 }
530 
531                 if (((ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
532                      (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) &&
533                     !importPortletSetup) {
534 
535                     continue;
536                 }
537 
538                 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
539                     !importPortletArchivedSetups) {
540 
541                     continue;
542                 }
543 
544                 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
545                     (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
546                     !importUserPreferences) {
547 
548                     continue;
549                 }
550 
551                 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
552                     plid = PortletKeys.PREFS_PLID_SHARED;
553                     ownerId = context.getGroupId();
554                 }
555 
556                 boolean defaultUser = GetterUtil.getBoolean(
557                     el.attributeValue("default-user"));
558 
559                 if (portletId == null) {
560                     portletId = el.attributeValue("portlet-id");
561                 }
562 
563                 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
564                     String userUuid = el.attributeValue("archive-user-uuid");
565                     String name = el.attributeValue("archive-name");
566 
567                     long userId = context.getUserId(userUuid);
568 
569                     PortletItem portletItem =
570                         PortletItemLocalServiceUtil.updatePortletItem(
571                             userId, groupId, name, portletId,
572                             PortletPreferences.class.getName());
573 
574                     plid = 0;
575                     ownerId = portletItem.getPortletItemId();
576                 }
577 
578                 if (defaultUser) {
579                     ownerId = defaultUserId;
580                 }
581 
582                 PortletPreferencesLocalServiceUtil.updatePreferences(
583                     ownerId, ownerType, plid, portletId, xml);
584             }
585         }
586 
587         if (preserveScopeLayoutId && (layout != null)) {
588             javax.portlet.PortletPreferences jxPreferences =
589                 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
590                     layout, portletId);
591 
592             try {
593                 jxPreferences.setValue(
594                     "lfr-scope-layout-id", String.valueOf(scopeLayoutId));
595 
596                 jxPreferences.store();
597             }
598             catch (Exception e) {
599                 throw new PortalException(e);
600             }
601             finally {
602                 context.setScopeLayoutId(scopeLayoutId);
603             }
604         }
605     }
606 
607     protected void readComments(PortletDataContext context, Element parentEl)
608         throws SystemException {
609 
610         try {
611             String xml = context.getZipEntryAsString(
612                 context.getSourceRootPath() + "/comments.xml");
613 
614             if (xml == null) {
615                 return;
616             }
617 
618             Document doc = SAXReaderUtil.read(xml);
619 
620             Element root = doc.getRootElement();
621 
622             List<Element> assets = root.elements("asset");
623 
624             for (Element asset : assets) {
625                 String path = asset.attributeValue("path");
626                 String className = asset.attributeValue("class-name");
627                 long classPK = GetterUtil.getLong(
628                     asset.attributeValue("class-pk"));
629 
630                 List<ObjectValuePair<String, byte[]>> entries =
631                     context.getZipFolderEntries(path);
632 
633                 List<MBMessage> messages = new ArrayList<MBMessage>();
634 
635                 for (ObjectValuePair<String, byte[]> entry : entries) {
636                     if (entry.getValue().length > 0) {
637                         MBMessage message = (MBMessage)context.fromXML(
638                             entry.getValue());
639 
640                         messages.add(message);
641                     }
642                 }
643 
644                 context.addComments(className, classPK, messages);
645             }
646         }
647         catch (Exception e) {
648             throw new SystemException(e);
649         }
650     }
651 
652     protected void readRatings(PortletDataContext context, Element parentEl)
653         throws SystemException {
654 
655         try {
656             String xml = context.getZipEntryAsString(
657                 context.getSourceRootPath() + "/ratings.xml");
658 
659             if (xml == null) {
660                 return;
661             }
662 
663             Document doc = SAXReaderUtil.read(xml);
664 
665             Element root = doc.getRootElement();
666 
667             List<Element> assets = root.elements("asset");
668 
669             for (Element asset : assets) {
670                 String path = asset.attributeValue("path");
671                 String className = asset.attributeValue("class-name");
672                 long classPK = GetterUtil.getLong(
673                     asset.attributeValue("class-pk"));
674 
675                 List<ObjectValuePair<String, byte[]>> entries =
676                     context.getZipFolderEntries(path);
677 
678                 List<RatingsEntry> ratingsEntries =
679                     new ArrayList<RatingsEntry>();
680 
681                 for (ObjectValuePair<String, byte[]> entry : entries) {
682                     if (entry.getValue().length > 0) {
683                         RatingsEntry rating = (RatingsEntry)context.fromXML(
684                             entry.getValue());
685 
686                         ratingsEntries.add(rating);
687                     }
688                 }
689 
690                 context.addRatingsEntries(
691                     className, new Long(classPK), ratingsEntries);
692             }
693         }
694         catch (Exception e) {
695             throw new SystemException(e);
696         }
697     }
698 
699     protected void readCategories(PortletDataContext context, Element parentEl)
700         throws SystemException {
701 
702         try {
703             String xml = context.getZipEntryAsString(
704                 context.getSourceRootPath() + "/categories.xml");
705 
706             if (xml == null) {
707                 return;
708             }
709 
710             Document doc = SAXReaderUtil.read(xml);
711 
712             Element root = doc.getRootElement();
713 
714             List<Element> assets = root.elements("asset");
715 
716             for (Element asset : assets) {
717                 String className = GetterUtil.getString(
718                     asset.attributeValue("class-name"));
719                 long classPK = GetterUtil.getLong(
720                     asset.attributeValue("class-pk"));
721                 String entries = GetterUtil.getString(
722                     asset.attributeValue("entries"));
723 
724                 context.addTagsCategories(
725                     className, new Long(classPK), StringUtil.split(entries));
726             }
727         }
728         catch (Exception e) {
729             throw new SystemException(e);
730         }
731     }
732 
733     protected void readTags(PortletDataContext context, Element parentEl)
734         throws SystemException {
735 
736         try {
737             String xml = context.getZipEntryAsString(
738                 context.getSourceRootPath() + "/tags.xml");
739 
740             if (xml == null) {
741                 return;
742             }
743 
744             Document doc = SAXReaderUtil.read(xml);
745 
746             Element root = doc.getRootElement();
747 
748             List<Element> assets = root.elements("asset");
749 
750             for (Element asset : assets) {
751                 String className = GetterUtil.getString(
752                     asset.attributeValue("class-name"));
753                 long classPK = GetterUtil.getLong(
754                     asset.attributeValue("class-pk"));
755                 String entries = GetterUtil.getString(
756                     asset.attributeValue("entries"));
757 
758                 context.addTagsEntries(
759                     className, new Long(classPK), StringUtil.split(entries));
760             }
761         }
762         catch (Exception e) {
763             throw new SystemException(e);
764         }
765     }
766 
767     private static Log _log = LogFactoryUtil.getLog(PortletImporter.class);
768 
769 }