1 package info.magnolia.cms.core.ie; 2 3 import info.magnolia.cms.beans.runtime.Document; 4 import info.magnolia.cms.core.Content; 5 import info.magnolia.cms.core.HierarchyManager; 6 import info.magnolia.cms.core.ItemType; 7 import info.magnolia.cms.core.ie.filters.ImportXmlRootFilter; 8 import info.magnolia.cms.core.ie.filters.MagnoliaV2Filter; 9 import info.magnolia.cms.core.ie.filters.VersionFilter; 10 import info.magnolia.cms.util.ContentUtil; 11 import info.magnolia.cms.util.NodeDataUtil; 12 import info.magnolia.context.MgnlContext; 13 14 import java.io.File ; 15 import java.io.FileInputStream ; 16 import java.io.FileNotFoundException ; 17 import java.io.FileOutputStream ; 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.OutputStream ; 21 import java.text.MessageFormat ; 22 import java.util.Iterator ; 23 import java.util.Properties ; 24 import java.util.zip.DeflaterOutputStream ; 25 import java.util.zip.GZIPInputStream ; 26 import java.util.zip.GZIPOutputStream ; 27 import java.util.zip.ZipInputStream ; 28 import java.util.zip.ZipOutputStream ; 29 30 import javax.jcr.ImportUUIDBehavior; 31 import javax.jcr.Node; 32 import javax.jcr.PathNotFoundException; 33 import javax.jcr.RepositoryException; 34 import javax.jcr.Session; 35 import javax.jcr.Workspace; 36 import javax.xml.transform.Source ; 37 import javax.xml.transform.sax.SAXTransformerFactory ; 38 import javax.xml.transform.stream.StreamSource ; 39 40 import org.apache.commons.io.IOUtils; 41 import org.apache.commons.lang.StringUtils; 42 import org.apache.commons.lang.exception.NestableRuntimeException; 43 import org.apache.xml.serialize.OutputFormat; 44 import org.apache.xml.serialize.XMLSerializer; 45 import org.slf4j.Logger; 46 import org.slf4j.LoggerFactory; 47 import org.xml.sax.ContentHandler ; 48 import org.xml.sax.InputSource ; 49 import org.xml.sax.SAXException ; 50 import org.xml.sax.XMLReader ; 51 import org.xml.sax.XMLFilter ; 52 import org.xml.sax.helpers.XMLReaderFactory ; 53 54 55 60 public class DataTransporter { 61 62 private static final int INDENT_VALUE = 2; 63 64 private static Logger log = LoggerFactory.getLogger(DataTransporter.class.getName()); 65 66 final static int bootstrapImportMode = ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING; 67 68 public static final String ZIP = ".zip"; 69 70 public static final String GZ = ".gz"; 71 72 public static final String XML = ".xml"; 73 74 public static final String PROPERTIES = ".properties"; 75 76 public static final String DOT = "."; 77 78 public static final String SLASH = "/"; 79 80 public static final String JCR_ROOT = "jcr:root"; 81 82 94 public static synchronized void importDocument(Document xmlDocument, String repositoryName, String basepath, 95 boolean keepVersionHistory, int importMode, boolean saveAfterImport, 96 boolean createBasepathIfNotExist) 97 throws IOException { 98 File xmlFile = xmlDocument.getFile(); 99 importFile(xmlFile, repositoryName, basepath, keepVersionHistory, importMode, saveAfterImport, 100 createBasepathIfNotExist); 101 } 102 103 115 public static synchronized void importFile(File xmlFile, String repositoryName, String basepath, 116 boolean keepVersionHistory, int importMode, boolean saveAfterImport, 117 boolean createBasepathIfNotExist) 118 throws IOException { 119 String name = xmlFile.getAbsolutePath(); 120 121 InputStream xmlStream = getInputStreamForFile(xmlFile); 122 importXmlStream(xmlStream, repositoryName, basepath, name, keepVersionHistory, importMode, saveAfterImport, 123 createBasepathIfNotExist); 124 } 125 126 131 public static void executeBootstrapImport(File xmlFile, String repositoryName) throws IOException { 132 String filenameWithoutExt = StringUtils.substringBeforeLast(xmlFile.getName(), DOT); 133 if (filenameWithoutExt.endsWith(XML)) { 134 filenameWithoutExt = StringUtils.substringBeforeLast(xmlFile.getName(), DOT); 137 } 138 String pathName = StringUtils.substringAfter(StringUtils.substringBeforeLast(filenameWithoutExt, DOT), DOT); 139 String basepath = SLASH + StringUtils.replace(pathName, DOT, SLASH); 140 141 if(xmlFile.getName().endsWith(PROPERTIES)){ 142 Properties properties = new Properties (); 143 properties.load(new FileInputStream (xmlFile)); 144 importProperties(properties , repositoryName); 145 } 146 else{ 147 DataTransporter.importFile(xmlFile, repositoryName, basepath, false, bootstrapImportMode, true, true); 148 } 149 } 150 151 156 public static void importProperties(Properties properties, String repositoryName) { 157 for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) { 158 String key = (String ) iter.next(); 159 String value = (String ) properties.get(key); 160 161 String name = StringUtils.substringAfterLast(key, "."); String path = StringUtils.substringBeforeLast(key, ".").replace('.', '/'); Content node = ContentUtil.getContent(repositoryName, path); 164 if(node != null){ 165 try { 166 NodeDataUtil.getOrCreate(node, name).setValue(value); 167 node.save(); 168 } 169 catch (RepositoryException e) { 170 log.error("can't set property " + key , e); 171 } 172 } 173 } 174 175 } 176 177 195 public static synchronized void importXmlStream(InputStream xmlStream, String repositoryName, String basepath, 196 String name, boolean keepVersionHistory, int importMode, 197 boolean saveAfterImport, boolean createBasepathIfNotExist) 198 throws IOException { 199 200 HierarchyManager hm = MgnlContext.getHierarchyManager(repositoryName); 201 Workspace ws = hm.getWorkspace(); 202 203 if (log.isDebugEnabled()) { 204 log.debug("Importing content into repository: [{}] from: [{}] into path: [{}]", new Object []{repositoryName, name, basepath}); 206 } 207 208 if (!hm.isExist(basepath) && createBasepathIfNotExist) { 209 try { 210 ContentUtil.createPath(hm, basepath, ItemType.CONTENT); 211 } 212 catch (RepositoryException e) { 213 log.error("can't create path [{}]", basepath); } 215 } 216 217 Session session = ws.getSession(); 218 219 try { 220 if (keepVersionHistory) { 221 session.importXML(basepath, xmlStream, importMode); 223 } 224 else { 225 XMLReader initialReader = XMLReaderFactory.createXMLReader(org.apache.xerces.parsers.SAXParser.class.getName()); 227 228 XMLFilter magnoliaV2Filter = null; 229 230 if (new File (name).isFile()) { 232 InputStream xslStream = getXslStreamForXmlFile(new File (name)); 233 if (xslStream != null) { 234 Source xslSource = new StreamSource (xslStream); 235 SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory ) SAXTransformerFactory.newInstance(); 236 XMLFilter xslFilter = saxTransformerFactory.newXMLFilter(xslSource); 237 magnoliaV2Filter = new MagnoliaV2Filter(xslFilter); 238 } 239 } 240 241 if (magnoliaV2Filter == null) { 242 magnoliaV2Filter = new MagnoliaV2Filter(initialReader); 243 } 244 245 XMLFilter versionFilter = new VersionFilter(magnoliaV2Filter); 246 XMLReader finalReader = new ImportXmlRootFilter(versionFilter); 247 248 ContentHandler handler = session.getImportContentHandler(basepath, importMode); 249 finalReader.setContentHandler(handler); 250 251 try { 253 finalReader.parse(new InputSource (xmlStream)); 254 } 255 finally { 256 IOUtils.closeQuietly(xmlStream); 257 } 258 259 if (((ImportXmlRootFilter) finalReader).rootNodeFound) { 260 String path = basepath; 261 if (!path.endsWith(SLASH)) { 262 path += SLASH; 263 } 264 265 Node dummyRoot = (Node) session.getItem(path + JCR_ROOT); 266 for (Iterator iter = dummyRoot.getNodes(); iter.hasNext();) { 267 Node child = (Node) iter.next(); 268 270 if (session.itemExists(path + child.getName())) { 271 session.getItem(path + child.getName()).remove(); 272 } 273 274 session.move(child.getPath(), path + child.getName()); 275 } 276 dummyRoot.remove(); 278 } 279 } 280 } 281 catch (Exception e) { 282 throw new NestableRuntimeException(e); 283 } 284 finally { 285 IOUtils.closeQuietly(xmlStream); 286 } 287 288 try { 289 if (saveAfterImport) { 290 session.save(); 291 } 292 } 293 catch (RepositoryException e) { 294 log.error(MessageFormat.format( 295 "Unable to save changes to the [{0}] repository due to a {1} Exception: {2}.", new Object []{repositoryName, e.getClass().getName(), e.getMessage()}), e); 297 throw new IOException (e.getMessage()); 298 } 299 } 300 301 305 protected static InputStream getXslStreamForXmlFile(File file) { 306 InputStream xslStream = null; 307 String xlsFilename = StringUtils.substringBeforeLast(file.getAbsolutePath(), ".") + ".xsl"; File xslFile = new File (xlsFilename); 309 if (xslFile.exists()) { 310 try { 311 xslStream = new FileInputStream (xslFile); 312 log.info("XSL file for [" + file.getName() + "] found (" + xslFile.getName() + ")"); } catch (FileNotFoundException e) { e.printStackTrace(); 315 } 316 } 317 return xslStream; 318 } 319 320 326 private static InputStream getInputStreamForFile(File xmlFile) throws IOException { 327 InputStream xmlStream; 328 if (xmlFile.getName().endsWith(ZIP)) { 330 xmlStream = new ZipInputStream ((new FileInputStream (xmlFile))); 331 } 332 else if (xmlFile.getName().endsWith(GZ)) { 333 xmlStream = new GZIPInputStream ((new FileInputStream (xmlFile))); 334 } 335 else { xmlStream = new FileInputStream (xmlFile); 337 } 338 return xmlStream; 339 } 340 341 342 public static void executeExport(OutputStream baseOutputStream, boolean keepVersionHistory, boolean format, 343 Session session, String basepath, String repository, String ext) throws IOException { 344 OutputStream outputStream = baseOutputStream; 345 if (ext.endsWith(ZIP)) { 346 outputStream = new ZipOutputStream (baseOutputStream); 347 } 348 else if (ext.endsWith(GZ)) { 349 outputStream = new GZIPOutputStream (baseOutputStream); 350 } 351 352 try { 353 if (keepVersionHistory) { 354 if (!format) { 357 session.exportSystemView(basepath, outputStream, false, false); 358 } 359 else { 360 parseAndFormat(outputStream, null, repository, basepath, session, false); 361 } 362 } 363 else { 364 XMLReader reader = new VersionFilter(XMLReaderFactory 367 .createXMLReader(org.apache.xerces.parsers.SAXParser.class.getName())); 368 parseAndFormat(outputStream, reader, repository, basepath, session, false); 369 } 370 } 371 catch (IOException e) { 372 throw new NestableRuntimeException(e); 373 } 374 catch (SAXException e) { 375 throw new NestableRuntimeException(e); 376 } 377 catch (RepositoryException e) { 378 throw new NestableRuntimeException(e); 379 } 380 381 if (outputStream instanceof DeflaterOutputStream ) { 384 ((DeflaterOutputStream ) outputStream).finish(); 385 } 386 387 baseOutputStream.flush(); 388 IOUtils.closeQuietly(baseOutputStream); 389 } 390 391 405 public static void parseAndFormat(OutputStream stream, XMLReader reader, String repository, String basepath, 406 Session session, boolean noRecurse) 407 throws IOException , SAXException , PathNotFoundException, RepositoryException { 408 409 if (reader == null) { 410 reader = XMLReaderFactory.createXMLReader(org.apache.xerces.parsers.SAXParser.class.getName()); 411 } 412 413 File tempFile = File.createTempFile("export-" + repository + session.getUserID(), "xml"); OutputStream fileStream = new FileOutputStream (tempFile); 416 417 try { 418 session.exportSystemView(basepath, fileStream, false, noRecurse); 419 } 420 finally { 421 IOUtils.closeQuietly(fileStream); 422 } 423 424 readFormatted(reader, tempFile, stream); 425 426 if (!tempFile.delete()) { 427 log.warn("Could not delete temporary export file {}", tempFile.getAbsolutePath()); } 429 } 430 431 439 protected static void readFormatted(XMLReader reader, File inputFile, OutputStream outputStream) 440 throws FileNotFoundException , IOException , SAXException { 441 InputStream fileInputStream = new FileInputStream (inputFile); 442 readFormatted(reader, fileInputStream, outputStream); 443 IOUtils.closeQuietly(fileInputStream); 444 } 445 446 454 protected static void readFormatted(XMLReader reader, InputStream inputStream, OutputStream outputStream) 455 throws FileNotFoundException , IOException , SAXException { 456 457 OutputFormat outputFormat = new OutputFormat(); 458 459 outputFormat.setPreserveSpace(false); outputFormat.setIndenting(true); 461 outputFormat.setIndent(INDENT_VALUE); 462 outputFormat.setLineWidth(120); 464 reader.setContentHandler(new XMLSerializer(outputStream, outputFormat)); 465 reader.parse(new InputSource (inputStream)); 466 467 IOUtils.closeQuietly(inputStream); 468 } 469 470 } 471 | Popular Tags |