001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * btatar 018 * 019 * $Id: XMLDirectoryReader.java 29029 2008-01-14 18:38:14Z ldoguin $ 020 */ 021 022package org.nuxeo.ecm.core.io.impl.plugins; 023 024import java.io.BufferedInputStream; 025import java.io.File; 026import java.io.FileFilter; 027import java.io.FileInputStream; 028import java.io.IOException; 029 030import org.dom4j.Document; 031import org.dom4j.DocumentException; 032import org.dom4j.io.SAXReader; 033import org.nuxeo.common.utils.FileTreeIterator; 034import org.nuxeo.common.utils.FileUtils; 035import org.nuxeo.common.utils.Path; 036import org.nuxeo.ecm.core.api.Blobs; 037import org.nuxeo.ecm.core.io.ExportConstants; 038import org.nuxeo.ecm.core.io.ExportedDocument; 039import org.nuxeo.ecm.core.io.impl.AbstractDocumentReader; 040import org.nuxeo.ecm.core.io.impl.ExportedDocumentImpl; 041 042/** 043 * @author bs@nuxeo.com 044 */ 045public class XMLDirectoryReader extends AbstractDocumentReader { 046 047 private File source; 048 049 private FileTreeIterator iterator; 050 051 public XMLDirectoryReader(String sourcePath) { 052 this(new File(sourcePath)); 053 } 054 055 public XMLDirectoryReader(File source) { 056 this.source = source; 057 iterator = new FileTreeIterator(source); 058 iterator.setFilter(new FileFilter() { 059 @Override 060 public boolean accept(File pathname) { 061 return pathname.isDirectory(); 062 } 063 }); 064 } 065 066 public Object getSource() { 067 return source; 068 } 069 070 public void setSource(File source) { 071 this.source = source; 072 } 073 074 @Override 075 public void close() { 076 source = null; 077 iterator = null; 078 } 079 080 @Override 081 public ExportedDocument read() throws IOException { 082 if (iterator.hasNext()) { 083 File dir = iterator.next(); 084 if (dir == null) { 085 return null; 086 } 087 // read document files 088 ExportedDocument xdoc = new ExportedDocumentImpl(); 089 for (File file : dir.listFiles()) { 090 if (file.isFile()) { 091 String name = file.getName(); 092 if (ExportConstants.DOCUMENT_FILE.equals(name)) { 093 Document doc = loadXML(file); 094 xdoc.setDocument(doc); 095 /* 096 * NXP-1688 Rux: the path was somehow left over when migrated from core 1.3.4 to 1.4.0. Pull 097 * back. 098 */ 099 xdoc.setPath(computeRelativePath(dir)); 100 } else if (name.endsWith(".xml")) { 101 xdoc.putDocument(FileUtils.getFileNameNoExt(file.getName()), loadXML(file)); 102 } else { // presume a blob 103 xdoc.putBlob(file.getName(), Blobs.createBlob(file)); 104 } 105 } 106 } 107 return xdoc; 108 } 109 return null; 110 } 111 112 /* 113 * NXP-1688 Rux: the path was somehow left over when migrated from core 1.3.4 to 1.4.0. Pull back. 114 */ 115 private Path computeRelativePath(File file) { 116 /* NXP-2507 Rux: preserve directory structure with slashes instead OS name separator */ 117 String subPathS = file.getAbsolutePath().substring(source.getAbsolutePath().length()); 118 subPathS = subPathS.replace(File.separatorChar, '/'); 119 return new Path(subPathS); 120 } 121 122 private static Document loadXML(File file) throws IOException { 123 BufferedInputStream in = null; 124 try { 125 in = new BufferedInputStream(new FileInputStream(file)); 126 return new SAXReader().read(in); 127 } catch (DocumentException e) { 128 IOException ioe = new IOException("Failed to read file document " + file + ": " + e.getMessage()); 129 ioe.setStackTrace(e.getStackTrace()); 130 throw ioe; 131 } finally { 132 if (in != null) { 133 in.close(); 134 } 135 } 136 } 137 138}