001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.LARFileException;
018    import com.liferay.portal.LARTypeException;
019    import com.liferay.portal.LayoutImportException;
020    import com.liferay.portal.LayoutPrototypeException;
021    import com.liferay.portal.LocaleException;
022    import com.liferay.portal.MissingReferenceException;
023    import com.liferay.portal.NoSuchLayoutException;
024    import com.liferay.portal.NoSuchLayoutPrototypeException;
025    import com.liferay.portal.NoSuchLayoutSetPrototypeException;
026    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
027    import com.liferay.portal.kernel.exception.PortalException;
028    import com.liferay.portal.kernel.language.LanguageUtil;
029    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
030    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
031    import com.liferay.portal.kernel.lar.ManifestSummary;
032    import com.liferay.portal.kernel.lar.MissingReference;
033    import com.liferay.portal.kernel.lar.MissingReferences;
034    import com.liferay.portal.kernel.lar.PortletDataContext;
035    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
036    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
037    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
038    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
039    import com.liferay.portal.kernel.lar.UserIdStrategy;
040    import com.liferay.portal.kernel.lar.lifecycle.ExportImportLifecycleConstants;
041    import com.liferay.portal.kernel.lar.lifecycle.ExportImportLifecycleManager;
042    import com.liferay.portal.kernel.lar.xstream.XStreamAliasRegistryUtil;
043    import com.liferay.portal.kernel.log.Log;
044    import com.liferay.portal.kernel.log.LogFactoryUtil;
045    import com.liferay.portal.kernel.search.Indexer;
046    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
047    import com.liferay.portal.kernel.util.ArrayUtil;
048    import com.liferay.portal.kernel.util.Constants;
049    import com.liferay.portal.kernel.util.GetterUtil;
050    import com.liferay.portal.kernel.util.LocaleUtil;
051    import com.liferay.portal.kernel.util.MapUtil;
052    import com.liferay.portal.kernel.util.ReleaseInfo;
053    import com.liferay.portal.kernel.util.StringUtil;
054    import com.liferay.portal.kernel.util.Tuple;
055    import com.liferay.portal.kernel.util.UnicodeProperties;
056    import com.liferay.portal.kernel.util.Validator;
057    import com.liferay.portal.kernel.xml.Document;
058    import com.liferay.portal.kernel.xml.Element;
059    import com.liferay.portal.kernel.xml.SAXReaderUtil;
060    import com.liferay.portal.kernel.zip.ZipReader;
061    import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
062    import com.liferay.portal.model.Group;
063    import com.liferay.portal.model.GroupConstants;
064    import com.liferay.portal.model.Layout;
065    import com.liferay.portal.model.LayoutConstants;
066    import com.liferay.portal.model.LayoutPrototype;
067    import com.liferay.portal.model.LayoutSet;
068    import com.liferay.portal.model.LayoutSetPrototype;
069    import com.liferay.portal.model.Portlet;
070    import com.liferay.portal.model.User;
071    import com.liferay.portal.model.impl.LayoutImpl;
072    import com.liferay.portal.security.permission.PermissionCacheUtil;
073    import com.liferay.portal.service.GroupLocalServiceUtil;
074    import com.liferay.portal.service.LayoutLocalServiceUtil;
075    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
076    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
077    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
078    import com.liferay.portal.service.PortletLocalServiceUtil;
079    import com.liferay.portal.service.ServiceContext;
080    import com.liferay.portal.service.ServiceContextThreadLocal;
081    import com.liferay.portal.service.persistence.LayoutUtil;
082    import com.liferay.portal.servlet.filters.cache.CacheUtil;
083    import com.liferay.portlet.journal.util.JournalContentUtil;
084    import com.liferay.portlet.sites.util.Sites;
085    import com.liferay.portlet.sites.util.SitesUtil;
086    
087    import java.io.File;
088    
089    import java.util.ArrayList;
090    import java.util.HashMap;
091    import java.util.HashSet;
092    import java.util.List;
093    import java.util.Locale;
094    import java.util.Map;
095    import java.util.Set;
096    
097    import org.apache.commons.lang.time.StopWatch;
098    
099    /**
100     * @author Brian Wing Shun Chan
101     * @author Joel Kozikowski
102     * @author Charles May
103     * @author Raymond Aug??
104     * @author Jorge Ferrer
105     * @author Bruno Farache
106     * @author Wesley Gong
107     * @author Zsigmond Rab
108     * @author Douglas Wong
109     * @author Julio Camarero
110     * @author Zsolt Berentey
111     */
112    public class LayoutImporter {
113    
114            public static LayoutImporter getInstance() {
115                    return _instance;
116            }
117    
118            public void importLayouts(
119                            long userId, long groupId, boolean privateLayout,
120                            Map<String, String[]> parameterMap, File file)
121                    throws Exception {
122    
123                    PortletDataContext portletDataContext = null;
124    
125                    try {
126                            ExportImportThreadLocal.setLayoutImportInProcess(true);
127    
128                            portletDataContext = getPortletDataContext(
129                                    userId, groupId, privateLayout, parameterMap, file);
130    
131                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
132                                    ExportImportLifecycleConstants.EVENT_LAYOUT_IMPORT_STARTED,
133                                    PortletDataContextFactoryUtil.clonePortletDataContext(
134                                            portletDataContext));
135    
136                            doImportLayouts(portletDataContext, userId);
137    
138                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
139                                    ExportImportLifecycleConstants.EVENT_LAYOUT_IMPORT_SUCCEEDED,
140                                    PortletDataContextFactoryUtil.clonePortletDataContext(
141                                            portletDataContext));
142                    }
143                    catch (Throwable t) {
144                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
145                                    ExportImportLifecycleConstants.EVENT_LAYOUT_IMPORT_FAILED,
146                                    PortletDataContextFactoryUtil.clonePortletDataContext(
147                                            portletDataContext),
148                                    t);
149    
150                            throw t;
151                    }
152                    finally {
153                            ExportImportThreadLocal.setLayoutImportInProcess(false);
154    
155                            CacheUtil.clearCache();
156                            JournalContentUtil.clearCache();
157                            PermissionCacheUtil.clearCache();
158                    }
159            }
160    
161            public MissingReferences validateFile(
162                            long userId, long groupId, boolean privateLayout,
163                            Map<String, String[]> parameterMap, File file)
164                    throws Exception {
165    
166                    ZipReader zipReader = null;
167    
168                    try {
169                            ExportImportThreadLocal.setLayoutValidationInProcess(true);
170    
171                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
172                                    groupId, privateLayout);
173    
174                            zipReader = ZipReaderFactoryUtil.getZipReader(file);
175    
176                            validateFile(
177                                    layoutSet.getCompanyId(), groupId, parameterMap, zipReader);
178    
179                            String userIdStrategyString = MapUtil.getString(
180                                    parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
181    
182                            UserIdStrategy userIdStrategy =
183                                    ExportImportHelperUtil.getUserIdStrategy(
184                                            userId, userIdStrategyString);
185    
186                            PortletDataContext portletDataContext =
187                                    PortletDataContextFactoryUtil.createImportPortletDataContext(
188                                            layoutSet.getCompanyId(), groupId, parameterMap,
189                                            userIdStrategy, zipReader);
190    
191                            portletDataContext.setPrivateLayout(privateLayout);
192    
193                            MissingReferences missingReferences =
194                                    ExportImportHelperUtil.validateMissingReferences(
195                                            portletDataContext);
196    
197                            Map<String, MissingReference> dependencyMissingReferences =
198                                    missingReferences.getDependencyMissingReferences();
199    
200                            if (!dependencyMissingReferences.isEmpty()) {
201                                    throw new MissingReferenceException(missingReferences);
202                            }
203    
204                            return missingReferences;
205                    }
206                    finally {
207                            ExportImportThreadLocal.setLayoutValidationInProcess(false);
208    
209                            if (zipReader != null) {
210                                    zipReader.close();
211                            }
212                    }
213            }
214    
215            protected void deleteMissingLayouts(
216                            PortletDataContext portletDataContext,
217                            List<String> sourceLayoutUuids, List<Layout> previousLayouts,
218                            ServiceContext serviceContext)
219                    throws Exception {
220    
221                    if (_log.isDebugEnabled() && !sourceLayoutUuids.isEmpty()) {
222                            _log.debug("Delete missing layouts");
223                    }
224    
225                    Map<Long, Long> layoutPlids =
226                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
227                                    Layout.class);
228    
229                    for (Layout layout : previousLayouts) {
230                            if (!sourceLayoutUuids.contains(layout.getUuid()) &&
231                                    !layoutPlids.containsValue(layout.getPlid())) {
232    
233                                    try {
234                                            LayoutLocalServiceUtil.deleteLayout(
235                                                    layout, false, serviceContext);
236                                    }
237                                    catch (NoSuchLayoutException nsle) {
238                                    }
239                            }
240                    }
241            }
242    
243            protected void doImportLayouts(
244                            PortletDataContext portletDataContext, long userId)
245                    throws Exception {
246    
247                    Map<String, String[]> parameterMap =
248                            portletDataContext.getParameterMap();
249    
250                    boolean deleteMissingLayouts = MapUtil.getBoolean(
251                            parameterMap, PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
252                            Boolean.TRUE.booleanValue());
253                    boolean deletePortletData = MapUtil.getBoolean(
254                            parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
255                    boolean importPermissions = MapUtil.getBoolean(
256                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
257                    boolean importLogo = MapUtil.getBoolean(
258                            parameterMap, PortletDataHandlerKeys.LOGO);
259                    boolean importLayoutSetSettings = MapUtil.getBoolean(
260                            parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
261    
262                    boolean layoutSetPrototypeLinkEnabled = MapUtil.getBoolean(
263                            parameterMap,
264                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED);
265    
266                    Group group = GroupLocalServiceUtil.getGroup(
267                            portletDataContext.getGroupId());
268    
269                    if (group.isLayoutSetPrototype()) {
270                            layoutSetPrototypeLinkEnabled = false;
271                    }
272    
273                    String layoutsImportMode = MapUtil.getString(
274                            parameterMap, PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
275                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID);
276    
277                    if (_log.isDebugEnabled()) {
278                            _log.debug("Delete portlet data " + deletePortletData);
279                            _log.debug("Import permissions " + importPermissions);
280                    }
281    
282                    StopWatch stopWatch = new StopWatch();
283    
284                    stopWatch.start();
285    
286                    LayoutCache layoutCache = new LayoutCache();
287    
288                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
289                            portletDataContext.getGroupId(),
290                            portletDataContext.isPrivateLayout());
291    
292                    long companyId = layoutSet.getCompanyId();
293    
294                    ServiceContext serviceContext =
295                            ServiceContextThreadLocal.getServiceContext();
296    
297                    if (serviceContext == null) {
298                            serviceContext = new ServiceContext();
299                    }
300    
301                    serviceContext.setCompanyId(companyId);
302                    serviceContext.setSignedIn(false);
303                    serviceContext.setUserId(userId);
304    
305                    ServiceContextThreadLocal.pushServiceContext(serviceContext);
306    
307                    // LAR validation
308    
309                    validateFile(
310                            companyId, portletDataContext.getGroupId(), parameterMap,
311                            portletDataContext.getZipReader());
312    
313                    // Source and target group id
314    
315                    Map<Long, Long> groupIds =
316                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
317                                    Group.class);
318    
319                    groupIds.put(
320                            portletDataContext.getSourceGroupId(),
321                            portletDataContext.getGroupId());
322    
323                    // Manifest
324    
325                    ManifestSummary manifestSummary =
326                            ExportImportHelperUtil.getManifestSummary(portletDataContext);
327    
328                    portletDataContext.setManifestSummary(manifestSummary);
329    
330                    // Layout and layout set prototype
331    
332                    Element layoutsElement = portletDataContext.getImportDataGroupElement(
333                            Layout.class);
334    
335                    String layoutSetPrototypeUuid = layoutsElement.attributeValue(
336                            "layout-set-prototype-uuid");
337    
338                    Element rootElement = portletDataContext.getImportDataRootElement();
339    
340                    Element headerElement = rootElement.element("header");
341    
342                    String larType = headerElement.attributeValue("type");
343    
344                    if (group.isLayoutPrototype() && larType.equals("layout-prototype")) {
345                            deleteMissingLayouts = false;
346    
347                            LayoutPrototype layoutPrototype =
348                                    LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
349                                            group.getClassPK());
350    
351                            String layoutPrototypeUuid = GetterUtil.getString(
352                                    headerElement.attributeValue("type-uuid"));
353    
354                            LayoutPrototype existingLayoutPrototype = null;
355    
356                            if (Validator.isNotNull(layoutPrototypeUuid)) {
357                                    try {
358                                            existingLayoutPrototype =
359                                                    LayoutPrototypeLocalServiceUtil.
360                                                            getLayoutPrototypeByUuidAndCompanyId(
361                                                                    layoutPrototypeUuid, companyId);
362                                    }
363                                    catch (NoSuchLayoutPrototypeException nslpe) {
364                                    }
365                            }
366    
367                            if (existingLayoutPrototype == null) {
368                                    List<Layout> layouts =
369                                            LayoutLocalServiceUtil.getLayoutsByLayoutPrototypeUuid(
370                                                    layoutPrototype.getUuid());
371    
372                                    layoutPrototype.setUuid(layoutPrototypeUuid);
373    
374                                    LayoutPrototypeLocalServiceUtil.updateLayoutPrototype(
375                                            layoutPrototype);
376    
377                                    for (Layout layout : layouts) {
378                                            layout.setLayoutPrototypeUuid(layoutPrototypeUuid);
379    
380                                            LayoutLocalServiceUtil.updateLayout(layout);
381                                    }
382                            }
383                    }
384                    else if (group.isLayoutSetPrototype() &&
385                                     larType.equals("layout-set-prototype")) {
386    
387                            LayoutSetPrototype layoutSetPrototype =
388                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
389                                            group.getClassPK());
390    
391                            String importedLayoutSetPrototypeUuid = GetterUtil.getString(
392                                    headerElement.attributeValue("type-uuid"));
393    
394                            LayoutSetPrototype existingLayoutSetPrototype = null;
395    
396                            if (Validator.isNotNull(importedLayoutSetPrototypeUuid)) {
397                                    try {
398                                            existingLayoutSetPrototype =
399                                                    LayoutSetPrototypeLocalServiceUtil.
400                                                            getLayoutSetPrototypeByUuidAndCompanyId(
401                                                                    importedLayoutSetPrototypeUuid, companyId);
402                                    }
403                                    catch (NoSuchLayoutSetPrototypeException nslspe) {
404                                    }
405                            }
406    
407                            if (existingLayoutSetPrototype == null) {
408                                    List<LayoutSet> layoutSets =
409                                            LayoutSetLocalServiceUtil.
410                                                    getLayoutSetsByLayoutSetPrototypeUuid(
411                                                            layoutSetPrototype.getUuid());
412    
413                                    layoutSetPrototype.setUuid(importedLayoutSetPrototypeUuid);
414    
415                                    LayoutSetPrototypeLocalServiceUtil.updateLayoutSetPrototype(
416                                            layoutSetPrototype);
417    
418                                    for (LayoutSet curLayoutSet : layoutSets) {
419                                            curLayoutSet.setLayoutSetPrototypeUuid(
420                                                    importedLayoutSetPrototypeUuid);
421    
422                                            LayoutSetLocalServiceUtil.updateLayoutSet(curLayoutSet);
423                                    }
424                            }
425                    }
426                    else if (larType.equals("layout-set-prototype")) {
427                            layoutSetPrototypeUuid = GetterUtil.getString(
428                                    headerElement.attributeValue("type-uuid"));
429                    }
430    
431                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
432                            layoutSet.setLayoutSetPrototypeUuid(layoutSetPrototypeUuid);
433                            layoutSet.setLayoutSetPrototypeLinkEnabled(
434                                    layoutSetPrototypeLinkEnabled);
435    
436                            LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
437                    }
438    
439                    // Look and feel
440    
441                    if (importLogo) {
442                            String logoPath = headerElement.attributeValue("logo-path");
443    
444                            byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
445                                    logoPath);
446    
447                            if (ArrayUtil.isNotEmpty(iconBytes)) {
448                                    LayoutSetLocalServiceUtil.updateLogo(
449                                            portletDataContext.getGroupId(),
450                                            portletDataContext.isPrivateLayout(), true, iconBytes);
451                            }
452                            else {
453                                    LayoutSetLocalServiceUtil.updateLogo(
454                                            portletDataContext.getGroupId(),
455                                            portletDataContext.isPrivateLayout(), false, (File)null);
456                            }
457                    }
458    
459                    _themeImporter.importTheme(portletDataContext, layoutSet);
460    
461                    if (importLayoutSetSettings) {
462                            String settings = GetterUtil.getString(
463                                    headerElement.elementText("settings"));
464    
465                            LayoutSetLocalServiceUtil.updateSettings(
466                                    portletDataContext.getGroupId(),
467                                    portletDataContext.isPrivateLayout(), settings);
468                    }
469    
470                    Element portletsElement = rootElement.element("portlets");
471    
472                    List<Element> portletElements = portletsElement.elements("portlet");
473    
474                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
475                            List<String> portletIds = new ArrayList<String>();
476    
477                            for (Element portletElement : portletElements) {
478                                    String portletId = portletElement.attributeValue("portlet-id");
479    
480                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
481                                            portletDataContext.getCompanyId(), portletId);
482    
483                                    if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
484                                            continue;
485                                    }
486    
487                                    portletIds.add(portletId);
488                            }
489    
490                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
491                                    "layout", ArrayUtil.toStringArray(portletIds), manifestSummary);
492                    }
493    
494                    // Read asset tags, expando tables, locks, and permissions to make them
495                    // available to the data handlers through the portlet data context
496    
497                    if (importPermissions) {
498                            for (Element portletElement : portletElements) {
499                                    String portletPath = portletElement.attributeValue("path");
500    
501                                    Document portletDocument = SAXReaderUtil.read(
502                                            portletDataContext.getZipEntryAsString(portletPath));
503    
504                                    _permissionImporter.checkRoles(
505                                            layoutCache, companyId, portletDataContext.getGroupId(),
506                                            userId, portletDocument.getRootElement());
507                            }
508    
509                            _permissionImporter.readPortletDataPermissions(portletDataContext);
510                    }
511    
512                    _portletImporter.readAssetTags(portletDataContext);
513                    _portletImporter.readExpandoTables(portletDataContext);
514                    _portletImporter.readLocks(portletDataContext);
515    
516                    // Layouts
517    
518                    Set<Layout> modifiedLayouts = new HashSet<Layout>();
519                    List<Layout> previousLayouts = LayoutUtil.findByG_P(
520                            portletDataContext.getGroupId(),
521                            portletDataContext.isPrivateLayout());
522    
523                    // Remove layouts that were deleted from the layout set prototype
524    
525                    if (Validator.isNotNull(layoutSetPrototypeUuid) &&
526                            layoutSetPrototypeLinkEnabled) {
527    
528                            LayoutSetPrototype layoutSetPrototype =
529                                    LayoutSetPrototypeLocalServiceUtil.
530                                            getLayoutSetPrototypeByUuidAndCompanyId(
531                                                    layoutSetPrototypeUuid, companyId);
532    
533                            for (Layout layout : previousLayouts) {
534                                    String sourcePrototypeLayoutUuid =
535                                            layout.getSourcePrototypeLayoutUuid();
536    
537                                    if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
538                                            continue;
539                                    }
540    
541                                    if (SitesUtil.isLayoutModifiedSinceLastMerge(layout)) {
542                                            modifiedLayouts.add(layout);
543    
544                                            continue;
545                                    }
546    
547                                    Layout sourcePrototypeLayout = LayoutUtil.fetchByUUID_G_P(
548                                            sourcePrototypeLayoutUuid, layoutSetPrototype.getGroupId(),
549                                            true);
550    
551                                    if (sourcePrototypeLayout == null) {
552                                            LayoutLocalServiceUtil.deleteLayout(
553                                                    layout, false, serviceContext);
554                                    }
555                            }
556                    }
557    
558                    List<Element> layoutElements = layoutsElement.elements();
559    
560                    if (_log.isDebugEnabled()) {
561                            if (!layoutElements.isEmpty()) {
562                                    _log.debug("Importing layouts");
563                            }
564                    }
565    
566                    List<String> sourceLayoutsUuids = new ArrayList<String>();
567    
568                    for (Element layoutElement : layoutElements) {
569                            importLayout(portletDataContext, sourceLayoutsUuids, layoutElement);
570                    }
571    
572                    // Delete portlet data
573    
574                    Map<Long, Layout> layouts =
575                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
576                                    Layout.class + ".layout");
577    
578                    if (deletePortletData) {
579                            if (_log.isDebugEnabled()) {
580                                    if (!portletElements.isEmpty()) {
581                                            _log.debug("Deleting portlet data");
582                                    }
583                            }
584    
585                            for (Element portletElement : portletElements) {
586                                    long layoutId = GetterUtil.getLong(
587                                            portletElement.attributeValue("layout-id"));
588    
589                                    long plid = LayoutConstants.DEFAULT_PLID;
590    
591                                    Layout layout = layouts.get(layoutId);
592    
593                                    if (layout != null) {
594                                            plid = layout.getPlid();
595                                    }
596    
597                                    portletDataContext.setPlid(plid);
598                                    portletDataContext.setPortletId(
599                                            portletElement.attributeValue("portlet-id"));
600    
601                                    _portletImporter.deletePortletData(portletDataContext);
602                            }
603                    }
604    
605                    // Import portlets
606    
607                    if (_log.isDebugEnabled()) {
608                            if (!portletElements.isEmpty()) {
609                                    _log.debug("Importing portlets");
610                            }
611                    }
612    
613                    for (Element portletElement : portletElements) {
614                            String portletPath = portletElement.attributeValue("path");
615                            String portletId = portletElement.attributeValue("portlet-id");
616                            long layoutId = GetterUtil.getLong(
617                                    portletElement.attributeValue("layout-id"));
618                            long oldPlid = GetterUtil.getLong(
619                                    portletElement.attributeValue("old-plid"));
620    
621                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
622                                    portletDataContext.getCompanyId(), portletId);
623    
624                            if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
625                                    continue;
626                            }
627    
628                            Layout layout = layouts.get(layoutId);
629    
630                            long plid = LayoutConstants.DEFAULT_PLID;
631    
632                            if (layout != null) {
633                                    plid = layout.getPlid();
634    
635                                    if (modifiedLayouts.contains(layout)) {
636                                            continue;
637                                    }
638                            }
639    
640                            portletDataContext.setPlid(plid);
641                            portletDataContext.setOldPlid(oldPlid);
642                            portletDataContext.setPortletId(portletId);
643    
644                            if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
645                                    PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
646                                            "portlet", portletId, manifestSummary);
647                            }
648    
649                            Document portletDocument = SAXReaderUtil.read(
650                                    portletDataContext.getZipEntryAsString(portletPath));
651    
652                            portletElement = portletDocument.getRootElement();
653    
654                            // The order of the import is important. You must always import the
655                            // portlet preferences first, then the portlet data, then the
656                            // portlet permissions. The import of the portlet data assumes that
657                            // portlet preferences already exist.
658    
659                            setPortletScope(portletDataContext, portletElement);
660    
661                            long portletPreferencesGroupId = portletDataContext.getGroupId();
662    
663                            Element portletDataElement = portletElement.element("portlet-data");
664    
665                            Map<String, Boolean> importPortletControlsMap =
666                                    ExportImportHelperUtil.getImportPortletControlsMap(
667                                            companyId, portletId, parameterMap, portletDataElement,
668                                            manifestSummary);
669    
670                            if (layout != null) {
671                                    portletPreferencesGroupId = layout.getGroupId();
672                            }
673    
674                            try {
675                                    ExportImportLifecycleManager.fireExportImportLifecycleEvent(
676                                            ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_STARTED,
677                                            PortletDataContextFactoryUtil.clonePortletDataContext(
678                                                    portletDataContext));
679    
680                                    // Portlet preferences
681    
682                                    _portletImporter.importPortletPreferences(
683                                            portletDataContext, layoutSet.getCompanyId(),
684                                            portletPreferencesGroupId, layout, portletElement, false,
685                                            importPortletControlsMap.get(
686                                                    PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
687                                            importPortletControlsMap.get(
688                                                    PortletDataHandlerKeys.PORTLET_DATA),
689                                            importPortletControlsMap.get(
690                                                    PortletDataHandlerKeys.PORTLET_SETUP),
691                                            importPortletControlsMap.get(
692                                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
693    
694                                    // Portlet data
695    
696                                    if (importPortletControlsMap.get(
697                                                    PortletDataHandlerKeys.PORTLET_DATA)) {
698    
699                                            _portletImporter.importPortletData(
700                                                    portletDataContext, portletDataElement);
701                                    }
702    
703                                    ExportImportLifecycleManager.fireExportImportLifecycleEvent(
704                                            ExportImportLifecycleConstants.
705                                                    EVENT_PORTLET_IMPORT_SUCCEEDED,
706                                            PortletDataContextFactoryUtil.clonePortletDataContext(
707                                                    portletDataContext));
708                            }
709                            catch (Throwable t) {
710                                    ExportImportLifecycleManager.fireExportImportLifecycleEvent(
711                                            ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_FAILED,
712                                            PortletDataContextFactoryUtil.clonePortletDataContext(
713                                                    portletDataContext),
714                                            t);
715    
716                                    throw t;
717                            }
718                            finally {
719                                    _portletImporter.resetPortletScope(
720                                            portletDataContext, portletPreferencesGroupId);
721                            }
722    
723                            // Portlet permissions
724    
725                            if (importPermissions) {
726                                    _permissionImporter.importPortletPermissions(
727                                            layoutCache, companyId, portletDataContext.getGroupId(),
728                                            userId, layout, portletElement, portletId);
729                            }
730    
731                            // Archived setups
732    
733                            _portletImporter.importPortletPreferences(
734                                    portletDataContext, layoutSet.getCompanyId(),
735                                    portletDataContext.getGroupId(), null, portletElement, false,
736                                    importPortletControlsMap.get(
737                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
738                                    importPortletControlsMap.get(
739                                            PortletDataHandlerKeys.PORTLET_DATA),
740                                    importPortletControlsMap.get(
741                                            PortletDataHandlerKeys.PORTLET_SETUP),
742                                    importPortletControlsMap.get(
743                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
744                    }
745    
746                    if (importPermissions) {
747                            if (userId > 0) {
748                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
749                                            User.class);
750    
751                                    indexer.reindex(userId);
752                            }
753                    }
754    
755                    // Import services
756    
757                    if (_log.isDebugEnabled() && !portletElements.isEmpty()) {
758                            _log.debug("Importing services");
759                    }
760    
761                    Element servicesElement = rootElement.element("services");
762    
763                    List<Element> serviceElements = servicesElement.elements("service");
764    
765                    for (Element serviceElement : serviceElements) {
766                            String path = serviceElement.attributeValue("path");
767    
768                            Document serviceDocument = SAXReaderUtil.read(
769                                    portletDataContext.getZipEntryAsString(path));
770    
771                            serviceElement = serviceDocument.getRootElement();
772    
773                            _portletImporter.importServicePortletPreferences(
774                                    portletDataContext, serviceElement);
775                    }
776    
777                    // Asset links
778    
779                    _portletImporter.readAssetLinks(portletDataContext);
780    
781                    // Delete missing layouts
782    
783                    if (deleteMissingLayouts) {
784                            deleteMissingLayouts(
785                                    portletDataContext, sourceLayoutsUuids, previousLayouts,
786                                    serviceContext);
787                    }
788    
789                    // Page count
790    
791                    layoutSet = LayoutSetLocalServiceUtil.updatePageCount(
792                            portletDataContext.getGroupId(),
793                            portletDataContext.isPrivateLayout());
794    
795                    // Site
796    
797                    GroupLocalServiceUtil.updateSite(portletDataContext.getGroupId(), true);
798    
799                    // Page priorities
800    
801                    updateLayoutPriorities(
802                            portletDataContext, layoutElements,
803                            portletDataContext.isPrivateLayout());
804    
805                    // Last merge time is updated only if there aren not any modified
806                    // layouts
807    
808                    if (layoutsImportMode.equals(
809                                    PortletDataHandlerKeys.
810                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
811    
812                            long lastMergeTime = System.currentTimeMillis();
813    
814                            for (Layout layout : layouts.values()) {
815                                    layout = LayoutLocalServiceUtil.getLayout(layout.getPlid());
816    
817                                    if (modifiedLayouts.contains(layout)) {
818                                            continue;
819                                    }
820    
821                                    UnicodeProperties typeSettingsProperties =
822                                            layout.getTypeSettingsProperties();
823    
824                                    typeSettingsProperties.setProperty(
825                                            Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
826    
827                                    LayoutUtil.update(layout);
828                            }
829    
830                            // The layout set may be stale because LayoutUtil#update(layout)
831                            // triggers LayoutSetPrototypeLayoutModelListener and that may have
832                            // updated this layout set
833    
834                            layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
835                                    layoutSet.getLayoutSetId());
836    
837                            UnicodeProperties settingsProperties =
838                                    layoutSet.getSettingsProperties();
839    
840                            String mergeFailFriendlyURLLayouts = settingsProperties.getProperty(
841                                    Sites.MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
842    
843                            if (Validator.isNull(mergeFailFriendlyURLLayouts) &&
844                                    modifiedLayouts.isEmpty()) {
845    
846                                    settingsProperties.setProperty(
847                                            Sites.LAST_MERGE_TIME, String.valueOf(lastMergeTime));
848    
849                                    LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
850                            }
851                    }
852    
853                    // Deletion system events
854    
855                    _deletionSystemEventImporter.importDeletionSystemEvents(
856                            portletDataContext);
857    
858                    if (_log.isInfoEnabled()) {
859                            _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
860                    }
861    
862                    ZipReader zipReader = portletDataContext.getZipReader();
863    
864                    zipReader.close();
865            }
866    
867            protected PortletDataContext getPortletDataContext(
868                            long userId, long groupId, boolean privateLayout,
869                            Map<String, String[]> parameterMap, File file)
870                    throws PortalException {
871    
872                    Group group = GroupLocalServiceUtil.getGroup(groupId);
873    
874                    String userIdStrategyString = MapUtil.getString(
875                            parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
876    
877                    UserIdStrategy userIdStrategy =
878                            ExportImportHelperUtil.getUserIdStrategy(
879                                    userId, userIdStrategyString);
880    
881                    ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
882    
883                    PortletDataContext portletDataContext =
884                            PortletDataContextFactoryUtil.createImportPortletDataContext(
885                                    group.getCompanyId(), groupId, parameterMap, userIdStrategy,
886                                    zipReader);
887    
888                    portletDataContext.setPrivateLayout(privateLayout);
889    
890                    return portletDataContext;
891            }
892    
893            protected void importLayout(
894                            PortletDataContext portletDataContext,
895                            List<String> sourceLayoutsUuids, Element layoutElement)
896                    throws Exception {
897    
898                    String action = layoutElement.attributeValue(Constants.ACTION);
899    
900                    if (!action.equals(Constants.SKIP)) {
901                            StagedModelDataHandlerUtil.importStagedModel(
902                                    portletDataContext, layoutElement);
903                    }
904    
905                    if (!action.equals(Constants.DELETE)) {
906                            sourceLayoutsUuids.add(layoutElement.attributeValue("uuid"));
907                    }
908            }
909    
910            protected void setPortletScope(
911                    PortletDataContext portletDataContext, Element portletElement) {
912    
913                    // Portlet data scope
914    
915                    String scopeLayoutUuid = GetterUtil.getString(
916                            portletElement.attributeValue("scope-layout-uuid"));
917                    String scopeLayoutType = GetterUtil.getString(
918                            portletElement.attributeValue("scope-layout-type"));
919    
920                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
921                    portletDataContext.setScopeType(scopeLayoutType);
922    
923                    // Layout scope
924    
925                    try {
926                            Group scopeGroup = null;
927    
928                            if (scopeLayoutType.equals("company")) {
929                                    scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
930                                            portletDataContext.getCompanyId());
931                            }
932                            else if (Validator.isNotNull(scopeLayoutUuid)) {
933                                    boolean privateLayout = GetterUtil.getBoolean(
934                                            portletElement.attributeValue("private-layout"));
935    
936                                    Layout scopeLayout =
937                                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
938                                                    scopeLayoutUuid, portletDataContext.getGroupId(),
939                                                    privateLayout);
940    
941                                    if (scopeLayout.hasScopeGroup()) {
942                                            scopeGroup = scopeLayout.getScopeGroup();
943                                    }
944                                    else {
945                                            String name = String.valueOf(scopeLayout.getPlid());
946    
947                                            scopeGroup = GroupLocalServiceUtil.addGroup(
948                                                    portletDataContext.getUserId(null),
949                                                    GroupConstants.DEFAULT_PARENT_GROUP_ID,
950                                                    Layout.class.getName(), scopeLayout.getPlid(),
951                                                    GroupConstants.DEFAULT_LIVE_GROUP_ID, name, null, 0,
952                                                    true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
953                                                    null, false, true, null);
954                                    }
955    
956                                    Group group = scopeLayout.getGroup();
957    
958                                    if (group.isStaged() && !group.isStagedRemotely()) {
959                                            try {
960                                                    Layout oldLayout =
961                                                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
962                                                                    scopeLayoutUuid,
963                                                                    portletDataContext.getSourceGroupId(),
964                                                                    privateLayout);
965    
966                                                    Group oldScopeGroup = oldLayout.getScopeGroup();
967    
968                                                    if (group.isStagingGroup()) {
969                                                            scopeGroup.setLiveGroupId(
970                                                                    oldScopeGroup.getGroupId());
971    
972                                                            GroupLocalServiceUtil.updateGroup(scopeGroup);
973                                                    }
974                                                    else {
975                                                            oldScopeGroup.setLiveGroupId(
976                                                                    scopeGroup.getGroupId());
977    
978                                                            GroupLocalServiceUtil.updateGroup(oldScopeGroup);
979                                                    }
980                                            }
981                                            catch (NoSuchLayoutException nsle) {
982                                                    if (_log.isWarnEnabled()) {
983                                                            _log.warn(nsle);
984                                                    }
985                                            }
986                                    }
987                            }
988    
989                            if (scopeGroup != null) {
990                                    portletDataContext.setScopeGroupId(scopeGroup.getGroupId());
991    
992                                    Map<Long, Long> groupIds =
993                                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
994                                                    Group.class);
995    
996                                    long oldScopeGroupId = GetterUtil.getLong(
997                                            portletElement.attributeValue("scope-group-id"));
998    
999                                    groupIds.put(oldScopeGroupId, scopeGroup.getGroupId());
1000                            }
1001                    }
1002                    catch (PortalException pe) {
1003                    }
1004                    catch (Exception e) {
1005                            _log.error(e, e);
1006                    }
1007            }
1008    
1009            protected void updateLayoutPriorities(
1010                    PortletDataContext portletDataContext, List<Element> layoutElements,
1011                    boolean privateLayout) {
1012    
1013                    Map<Long, Layout> layouts =
1014                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
1015                                    Layout.class + ".layout");
1016    
1017                    Map<Long, Integer> layoutPriorities = new HashMap<Long, Integer>();
1018    
1019                    int maxPriority = Integer.MIN_VALUE;
1020    
1021                    for (Element layoutElement : layoutElements) {
1022                            String action = layoutElement.attributeValue(Constants.ACTION);
1023    
1024                            if (action.equals(Constants.SKIP)) {
1025    
1026                                    // We only want to update priorites if there are no elements
1027                                    // with the SKIP action
1028    
1029                                    return;
1030                            }
1031    
1032                            if (action.equals(Constants.ADD)) {
1033                                    long layoutId = GetterUtil.getLong(
1034                                            layoutElement.attributeValue("layout-id"));
1035    
1036                                    Layout layout = layouts.get(layoutId);
1037    
1038                                    int layoutPriority = GetterUtil.getInteger(
1039                                            layoutElement.attributeValue("layout-priority"));
1040    
1041                                    layoutPriorities.put(layout.getPlid(), layoutPriority);
1042    
1043                                    if (maxPriority < layoutPriority) {
1044                                            maxPriority = layoutPriority;
1045                                    }
1046                            }
1047                    }
1048    
1049                    List<Layout> layoutSetLayouts = LayoutLocalServiceUtil.getLayouts(
1050                            portletDataContext.getGroupId(), privateLayout);
1051    
1052                    for (Layout layout : layoutSetLayouts) {
1053                            if (layoutPriorities.containsKey(layout.getPlid())) {
1054                                    layout.setPriority(layoutPriorities.get(layout.getPlid()));
1055                            }
1056                            else {
1057                                    layout.setPriority(++maxPriority);
1058                            }
1059    
1060                            LayoutLocalServiceUtil.updateLayout(layout);
1061                    }
1062            }
1063    
1064            protected void validateFile(
1065                            long companyId, long groupId, Map<String, String[]> parameterMap,
1066                            ZipReader zipReader)
1067                    throws Exception {
1068    
1069                    // XML
1070    
1071                    String xml = zipReader.getEntryAsString("/manifest.xml");
1072    
1073                    if (xml == null) {
1074                            throw new LARFileException("manifest.xml not found in the LAR");
1075                    }
1076    
1077                    Element rootElement = null;
1078    
1079                    try {
1080                            Document document = SAXReaderUtil.read(xml);
1081    
1082                            rootElement = document.getRootElement();
1083                    }
1084                    catch (Exception e) {
1085                            throw new LARFileException(e);
1086                    }
1087    
1088                    // Build compatibility
1089    
1090                    int buildNumber = ReleaseInfo.getBuildNumber();
1091    
1092                    Element headerElement = rootElement.element("header");
1093    
1094                    int importBuildNumber = GetterUtil.getInteger(
1095                            headerElement.attributeValue("build-number"));
1096    
1097                    if (buildNumber != importBuildNumber) {
1098                            throw new LayoutImportException(
1099                                    "LAR build number " + importBuildNumber + " does not match " +
1100                                            "portal build number " + buildNumber);
1101                    }
1102    
1103                    // Type
1104    
1105                    String larType = headerElement.attributeValue("type");
1106    
1107                    if (!larType.equals("layout-prototype") &&
1108                            !larType.equals("layout-set") &&
1109                            !larType.equals("layout-set-prototype")) {
1110    
1111                            throw new LARTypeException(larType);
1112                    }
1113    
1114                    Group group = GroupLocalServiceUtil.fetchGroup(groupId);
1115    
1116                    String layoutsImportMode = MapUtil.getString(
1117                            parameterMap, PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE);
1118    
1119                    if (larType.equals("layout-prototype") && !group.isLayoutPrototype() &&
1120                            !layoutsImportMode.equals(
1121                                    PortletDataHandlerKeys.
1122                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1123    
1124                            throw new LARTypeException(
1125                                    "A page template can only be imported to a page template");
1126                    }
1127    
1128                    if (larType.equals("layout-set")) {
1129                            if (group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
1130                                    throw new LARTypeException(
1131                                            "A site can only be imported to a site");
1132                            }
1133    
1134                            long sourceCompanyGroupId = GetterUtil.getLong(
1135                                    headerElement.attributeValue("company-group-id"));
1136                            long sourceGroupId = GetterUtil.getLong(
1137                                    headerElement.attributeValue("group-id"));
1138    
1139                            if (group.isCompany() ^ (sourceCompanyGroupId == sourceGroupId)) {
1140                                    throw new LARTypeException(
1141                                            "A company site can only be imported to a company site");
1142                            }
1143                    }
1144    
1145                    if (larType.equals("layout-set-prototype") &&
1146                            !group.isLayoutSetPrototype() &&
1147                            !layoutsImportMode.equals(
1148                                    PortletDataHandlerKeys.
1149                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
1150    
1151                            throw new LARTypeException(
1152                                    "A site template can only be imported to a site template");
1153                    }
1154    
1155                    // Available locales
1156    
1157                    Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1158                            StringUtil.split(
1159                                    headerElement.attributeValue("available-locales")));
1160    
1161                    Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1162                            groupId);
1163    
1164                    for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1165                            if (!ArrayUtil.contains(
1166                                            targetAvailableLocales, sourceAvailableLocale)) {
1167    
1168                                    LocaleException le = new LocaleException(
1169                                            LocaleException.TYPE_EXPORT_IMPORT);
1170    
1171                                    le.setSourceAvailableLocales(sourceAvailableLocales);
1172                                    le.setTargetAvailableLocales(targetAvailableLocales);
1173    
1174                                    throw le;
1175                            }
1176                    }
1177    
1178                    // Layout prototypes validity
1179    
1180                    Element layoutsElement = rootElement.element(
1181                            Layout.class.getSimpleName());
1182    
1183                    validateLayoutPrototypes(companyId, layoutsElement);
1184            }
1185    
1186            protected void validateLayoutPrototypes(
1187                            long companyId, Element layoutsElement)
1188                    throws Exception {
1189    
1190                    List<Tuple> missingLayoutPrototypes = new ArrayList<Tuple>();
1191    
1192                    String layoutSetPrototypeUuid = layoutsElement.attributeValue(
1193                            "layout-set-prototype-uuid");
1194    
1195                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
1196                            try {
1197                                    LayoutSetPrototypeLocalServiceUtil.
1198                                            getLayoutSetPrototypeByUuidAndCompanyId(
1199                                                    layoutSetPrototypeUuid, companyId);
1200                            }
1201                            catch (NoSuchLayoutSetPrototypeException nlspe) {
1202                                    String layoutSetPrototypeName = layoutsElement.attributeValue(
1203                                            "layout-set-prototype-name");
1204    
1205                                    missingLayoutPrototypes.add(
1206                                            new Tuple(
1207                                                    LayoutSetPrototype.class.getName(),
1208                                                    layoutSetPrototypeUuid, layoutSetPrototypeName));
1209                            }
1210                    }
1211    
1212                    List<Element> layoutElements = layoutsElement.elements();
1213    
1214                    for (Element layoutElement : layoutElements) {
1215                            String action = layoutElement.attributeValue(Constants.ACTION);
1216    
1217                            if (action.equals(Constants.SKIP)) {
1218                                    continue;
1219                            }
1220    
1221                            String layoutPrototypeUuid = GetterUtil.getString(
1222                                    layoutElement.attributeValue("layout-prototype-uuid"));
1223    
1224                            if (Validator.isNotNull(layoutPrototypeUuid)) {
1225                                    try {
1226                                            LayoutPrototypeLocalServiceUtil.
1227                                                    getLayoutPrototypeByUuidAndCompanyId(
1228                                                            layoutPrototypeUuid, companyId);
1229                                    }
1230                                    catch (NoSuchLayoutPrototypeException nslpe) {
1231                                            String layoutPrototypeName = GetterUtil.getString(
1232                                                    layoutElement.attributeValue("layout-prototype-name"));
1233    
1234                                            missingLayoutPrototypes.add(
1235                                                    new Tuple(
1236                                                            LayoutPrototype.class.getName(),
1237                                                            layoutPrototypeUuid, layoutPrototypeName));
1238                                    }
1239                            }
1240                    }
1241    
1242                    if (!missingLayoutPrototypes.isEmpty()) {
1243                            throw new LayoutPrototypeException(missingLayoutPrototypes);
1244                    }
1245            }
1246    
1247            private LayoutImporter() {
1248                    XStreamAliasRegistryUtil.register(LayoutImpl.class, "Layout");
1249            }
1250    
1251            private static Log _log = LogFactoryUtil.getLog(LayoutImporter.class);
1252    
1253            private static LayoutImporter _instance = new LayoutImporter();
1254    
1255            private DeletionSystemEventImporter _deletionSystemEventImporter =
1256                    DeletionSystemEventImporter.getInstance();
1257            private PermissionImporter _permissionImporter =
1258                    PermissionImporter.getInstance();
1259            private PortletImporter _portletImporter = PortletImporter.getInstance();
1260            private ThemeImporter _themeImporter = ThemeImporter.getInstance();
1261    
1262    }