/* * Copyright (C) 2003-2017 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.management.wiki.operations; import org.exoplatform.management.common.FileEntry; import org.exoplatform.management.common.exportop.ActivitiesExportTask; import org.exoplatform.management.common.exportop.SpaceMetadataExportTask; import org.exoplatform.management.common.importop.AbstractJCRImportOperationHandler; import org.exoplatform.management.common.importop.ActivityImportOperationInterface; import org.exoplatform.management.common.importop.FileImportOperationInterface; import org.exoplatform.portal.config.UserACL; import org.exoplatform.services.cache.CacheService; import org.exoplatform.services.jcr.RepositoryService; import org.exoplatform.social.core.activity.model.ExoSocialActivity; import org.exoplatform.social.core.manager.ActivityManager; import org.exoplatform.social.core.space.model.Space; import org.exoplatform.social.core.space.spi.SpaceService; import org.exoplatform.social.core.storage.api.ActivityStorage; import org.exoplatform.social.core.storage.api.IdentityStorage; import org.exoplatform.wiki.mow.api.Page; import org.exoplatform.wiki.mow.api.Wiki; import org.exoplatform.wiki.mow.api.WikiType; import org.exoplatform.wiki.mow.core.api.MOWService; import org.exoplatform.wiki.mow.core.api.wiki.WikiImpl; import org.exoplatform.wiki.service.WikiService; import org.gatein.common.logging.Logger; import org.gatein.common.logging.LoggerFactory; import org.gatein.management.api.exceptions.OperationException; import org.gatein.management.api.operation.OperationAttributes; import org.gatein.management.api.operation.OperationContext; import org.gatein.management.api.operation.OperationNames; import org.gatein.management.api.operation.ResultHandler; import org.gatein.management.api.operation.model.NoResultModel; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; /** * Created by The eXo Platform SAS Author : eXoPlatform exo@exoplatform.com Mar * 5, 2014 */ public class WikiDataImportResource extends AbstractJCRImportOperationHandler implements ActivityImportOperationInterface, FileImportOperationInterface { /** The Constant log. */ final private static Logger log = LoggerFactory.getLogger(WikiDataImportResource.class); /** The wiki type. */ private WikiType wikiType; /** The mow service. */ private MOWService mowService; /** The wiki service. */ private WikiService wikiService; /** The cache service. */ private CacheService cacheService; /** * Instantiates a new wiki data import resource. * * @param wikiType the wiki type */ public WikiDataImportResource(WikiType wikiType) { this.wikiType = wikiType; } /** * {@inheritDoc} */ @Override public void execute(OperationContext operationContext, ResultHandler resultHandler) throws OperationException { spaceService = operationContext.getRuntimeContext().getRuntimeComponent(SpaceService.class); userACL = operationContext.getRuntimeContext().getRuntimeComponent(UserACL.class); mowService = operationContext.getRuntimeContext().getRuntimeComponent(MOWService.class); repositoryService = operationContext.getRuntimeContext().getRuntimeComponent(RepositoryService.class); activityManager = operationContext.getRuntimeContext().getRuntimeComponent(ActivityManager.class); activityStorage = operationContext.getRuntimeContext().getRuntimeComponent(ActivityStorage.class); identityStorage = operationContext.getRuntimeContext().getRuntimeComponent(IdentityStorage.class); wikiService = operationContext.getRuntimeContext().getRuntimeComponent(WikiService.class); cacheService = operationContext.getRuntimeContext().getRuntimeComponent(CacheService.class); OperationAttributes attributes = operationContext.getAttributes(); List<String> filters = attributes.getValues("filter"); // "replace-existing" attribute. Defaults to false. boolean replaceExisting = filters.contains("replace-existing:true"); // "create-space" attribute. Defaults to false. boolean createSpace = filters.contains("create-space:true"); InputStream attachmentInputStream = getAttachementInputStream(operationContext); increaseCurrentTransactionTimeOut(operationContext); try { // extract data from zip Map<String, List<FileEntry>> contentsByOwner = extractDataFromZip(attachmentInputStream); for (String wikiOwner : contentsByOwner.keySet()) { List<FileEntry> fileEntries = contentsByOwner.get(wikiOwner); if (WikiType.GROUP.equals(wikiType)) { FileEntry spaceMetadataFile = getAndRemoveFileByPath(fileEntries, SpaceMetadataExportTask.FILENAME); if (spaceMetadataFile != null && spaceMetadataFile.getFile().exists()) { boolean spaceCreatedOrAlreadyExists = createSpaceIfNotExists(spaceMetadataFile.getFile(), createSpace); if (!spaceCreatedOrAlreadyExists) { log.warn("Import of wiki '" + wikiOwner + "' is ignored. Turn on 'create-space:true' option if you want to automatically create the space."); continue; } } } FileEntry activitiesFile = getAndRemoveFileByPath(fileEntries, ActivitiesExportTask.FILENAME); WikiImpl wiki = mowService.getWikiStore().getWikiContainer(wikiType).contains(wikiOwner); if (wiki != null) { if (replaceExisting) { log.info("Overwrite existing wiki for owner : '" + wikiType + ":" + wikiOwner + "' (replace-existing=true). Delete: " + wiki.getWikiHome().getJCRPageNode().getPath()); deleteActivities(wiki.getType(), wiki.getOwner()); } else { log.info("Ignore existing wiki for owner : '" + wikiType + ":" + wikiOwner + "' (replace-existing=false)."); continue; } } else { wiki = mowService.getWikiStore().addWiki(wikiType, wikiOwner); } String workspace = mowService.getSession().getJCRSession().getWorkspace().getName(); Collections.sort(fileEntries); for (FileEntry fileEntry : fileEntries) { importNode(fileEntry, workspace, false); } // Import activities if (activitiesFile != null && activitiesFile.getFile().exists()) { String spacePrettyName = null; if (WikiType.GROUP.equals(wikiType)) { Space space = spaceService.getSpaceByGroupId(wikiOwner); spacePrettyName = space.getPrettyName(); } log.info("Importing Wiki activities"); importActivities(activitiesFile.getFile(), spacePrettyName, true); } } } catch (Exception e) { throw new OperationException(OperationNames.IMPORT_RESOURCE, "Unable to import wiki content of type: " + wikiType, e); } finally { restoreDefaultTransactionTimeOut(operationContext); if (attachmentInputStream != null) { try { attachmentInputStream.close(); } catch (IOException e) { // Nothing to do } } } clearCaches(cacheService, "wiki"); resultHandler.completed(NoResultModel.INSTANCE); } /** * {@inheritDoc} */ public String getManagedFilesPrefix() { return "wiki/" + wikiType.name().toLowerCase() + "/"; } /** * {@inheritDoc} */ public boolean isUnKnownFileFormat(String filePath) { return !filePath.endsWith(".xml") && !filePath.endsWith(SpaceMetadataExportTask.FILENAME) && !filePath.contains(ActivitiesExportTask.FILENAME); } /** * {@inheritDoc} */ public boolean addSpecialFile(List<FileEntry> fileEntries, String filePath, File file) { if (filePath.endsWith(SpaceMetadataExportTask.FILENAME)) { fileEntries.add(new FileEntry(SpaceMetadataExportTask.FILENAME, file)); return true; } else if (filePath.endsWith(ActivitiesExportTask.FILENAME)) { fileEntries.add(new FileEntry(ActivitiesExportTask.FILENAME, file)); return true; } return false; } /** * {@inheritDoc} */ public String extractIdFromPath(String path) { int beginIndex = ("wiki/" + wikiType + "/___").length(); int endIndex = path.indexOf("---/", beginIndex); return path.substring(beginIndex, endIndex); } /** * {@inheritDoc} */ public void attachActivityToEntity(ExoSocialActivity activity, ExoSocialActivity comment) throws Exception { if (comment != null) { return; } String pageId = activity.getTemplateParams().get("page_id"); String pageOwner = activity.getTemplateParams().get("page_owner"); String pageType = activity.getTemplateParams().get("page_type"); Page page = wikiService.getPageOfWikiByName(pageType, pageOwner, pageId); page.setActivityId(activity.getId()); wikiService.updatePage(page, null); } /** * {@inheritDoc} */ public boolean isActivityNotValid(ExoSocialActivity activity, ExoSocialActivity comment) throws Exception { if (comment == null) { String pageId = activity.getTemplateParams().get("page_id"); String pageOwner = activity.getTemplateParams().get("page_owner"); String pageType = activity.getTemplateParams().get("page_type"); Page page = null; if (pageId != null && pageOwner != null && pageType != null) { page = wikiService.getPageOfWikiByName(pageType, pageOwner, pageId); } if (page == null) { log.warn("Wiki page not found. Cannot import activity '" + activity.getTitle() + "'."); return true; } return false; } else { return false; } } /** * Delete activities. * * @param wikiType the wiki type * @param wikiOwner the wiki owner * @throws Exception the exception */ private void deleteActivities(String wikiType, String wikiOwner) throws Exception { // Delete Forum activity stream Wiki wiki = wikiService.getWikiByTypeAndOwner(wikiType, wikiOwner); if (wiki == null) { return; } Page homePage = wiki.getWikiHome(); List<Page> pages = new ArrayList<Page>(); computeChildPages(pages, homePage); List<String> activityIds = new ArrayList<String>(); for (Page page : pages) { activityIds.add(page.getActivityId()); } deleteActivitiesById(activityIds); } /** * Compute child pages. * * @param pages the pages * @param parentPage the parent page * @throws Exception the exception */ private void computeChildPages(List<Page> pages, Page parentPage) throws Exception { pages.add(parentPage); List<Page> chilPages = wikiService.getChildrenPageOf(parentPage); for (Page childPage : chilPages) { computeChildPages(pages, childPage); } } }