/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Astroboa 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.engine.jcr.io; import java.io.InputStream; import java.net.URI; import javax.jcr.Session; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.time.DurationFormatUtils; import org.betaconceptframework.astroboa.api.model.exception.CmsException; import org.betaconceptframework.astroboa.api.model.io.ImportConfiguration; import org.betaconceptframework.astroboa.api.model.io.ImportReport; import org.betaconceptframework.astroboa.api.service.ContentService; import org.betaconceptframework.astroboa.context.AstroboaClientContext; import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder; import org.betaconceptframework.astroboa.engine.definition.RepositoryEntityResolver; import org.betaconceptframework.astroboa.engine.jcr.dao.JcrDaoSupport; import org.betaconceptframework.astroboa.engine.jcr.dao.RepositoryUserDao; import org.betaconceptframework.astroboa.engine.jcr.dao.SpaceDao; import org.betaconceptframework.astroboa.engine.jcr.dao.TaxonomyDao; import org.betaconceptframework.astroboa.engine.jcr.dao.TopicDao; import org.betaconceptframework.astroboa.engine.jcr.query.CmsQueryHandler; import org.betaconceptframework.astroboa.engine.jcr.util.BinaryChannelUtils; import org.betaconceptframework.astroboa.engine.jcr.util.CmsRepositoryEntityUtils; import org.betaconceptframework.astroboa.engine.model.jaxb.Repository; import org.betaconceptframework.astroboa.model.impl.io.ImportReportImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** * This class is responsible to import content from a provided URL * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ @Transactional(readOnly = true, rollbackFor = CmsException.class, propagation=Propagation.REQUIRED) public class ImportBean extends JcrDaoSupport{ private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private RepositoryEntityResolver repositoryEntityResolver; @Autowired //Instead of injecting ContentDao //We inject ContentService so that //aspect during content object save is triggered private ContentService contentService; @Autowired private RepositoryUserDao repositoryUserDao; @Autowired private TaxonomyDao taxonomyDao; @Autowired private TopicDao topicDao; @Autowired private SpaceDao spaceDao; @Autowired private CmsRepositoryEntityUtils cmsRepositoryEntityUtils; @Autowired private CmsQueryHandler cmsQueryHandler; @Autowired private BinaryChannelUtils binaryChannelUtils; @Transactional(readOnly = false, rollbackFor = CmsException.class, propagation=Propagation.REQUIRES_NEW) public void importRepositoryContentFromURI(URI contentSource, AstroboaClientContext clientContext, ImportReport importReport, ImportConfiguration importConfiguration){ long start = System.currentTimeMillis(); if (clientContext == null){ throw new CmsException("Astroboa client context is not provided. Export failed"); } InputStream streamSource = null; ContentSourceExtractor contentSourceExtractor = null; try{ //Register client context AstroboaClientContextHolder.registerClientContext(clientContext, true); if (contentSource != null){ contentSourceExtractor = new ContentSourceExtractor(); streamSource = contentSourceExtractor.extractStream(contentSource); if (streamSource == null){ throw new Exception("Could not locate xml content source in URL "+contentSource.toString()); } performImport(importReport, streamSource, false, Repository.class, getSession(), importConfiguration); } } catch(CmsException e){ addErrorToReport(importReport, e, contentSource.toString()); throw e; } catch(Exception e){ addErrorToReport(importReport, e, contentSource.toString()); throw new CmsException(e); } finally{ completeImport(importReport, start, streamSource); if (contentSourceExtractor != null){ contentSourceExtractor.dispose(); } } } @Transactional(readOnly = false, rollbackFor = CmsException.class, propagation=Propagation.REQUIRED) public <T> T importContentFromString(String contentSource, ImportReport importReport, Class<T> classToBeImported, AstroboaClientContext clientContext,ImportConfiguration importConfiguration){ long start = System.currentTimeMillis(); InputStream xml = null; try{ if (clientContext != null){ AstroboaClientContextHolder.registerClientContext(clientContext, true); } if (contentSource != null){ //Identify whether source is XML or JSON boolean sourceIsXML = contentSource.startsWith("<?xml version=\"1.0\""); xml = IOUtils.toInputStream(contentSource, "UTF-8"); if (xml == null){ throw new Exception("Content source is invalid "+ contentSource); } return performImport(importReport, xml, ! sourceIsXML, classToBeImported, getSession(), importConfiguration); } } catch(CmsException e){ addErrorToReport(importReport, e, contentSource); throw e; } catch(Exception e){ addErrorToReport(importReport, e, contentSource); throw new CmsException(e); } finally{ completeImport(importReport, start, xml); } return null; } private <T> T performImport(ImportReport importReport, InputStream source, boolean jsonSource, Class<T> classToBeImported, Session session, ImportConfiguration importConfiguration) { Deserializer deserializer = new Deserializer(); deserializer.setContentService(contentService); deserializer.setRepositoryEntityResolver(repositoryEntityResolver); deserializer.setRepositoryUserDao(repositoryUserDao); deserializer.setTaxonomyDao(taxonomyDao); deserializer.setTopicDao(topicDao); deserializer.setSpaceDao(spaceDao); deserializer.setCmsQueryHandler(cmsQueryHandler); deserializer.setCmsRepositoryEntityUtils(cmsRepositoryEntityUtils); deserializer.setSession(session); deserializer.setImportReport(importReport); deserializer.setBinaryChannelUtils(binaryChannelUtils); return (T) deserializer.deserializeContent(source, jsonSource, classToBeImported,importConfiguration); } private void completeImport(ImportReport importReport, long start, InputStream xml) { logger.debug("Imported {} entities (" + "{} repository users, {} taxonomies, " + "{} spaces, {} contentObjects"+ ") in {} ", new Object[]{ ((ImportReportImpl)importReport).getTotalCountOfImportedEntities(), importReport.getNumberOfRepositoryUsersImported(), importReport.getNumberOfTaxonomiesImported(), importReport.getNumberOfSpacesImported(), importReport.getNumberOfContentObjectsImported(), DurationFormatUtils.formatDurationHMS(System.currentTimeMillis()-start) } ); IOUtils.closeQuietly(xml); } private void addErrorToReport(ImportReport importReport, Exception e, String contentSource) { logger.error(contentSource,e); ((ImportReportImpl)importReport).getErrors().add(e.getMessage()); } }