001 /*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019 package org.crsh.jcr;
020
021 import org.crsh.util.Safe;
022 import org.xml.sax.Attributes;
023 import org.xml.sax.ContentHandler;
024 import org.xml.sax.SAXException;
025 import org.xml.sax.helpers.DefaultHandler;
026
027 import javax.xml.parsers.SAXParser;
028 import javax.xml.parsers.SAXParserFactory;
029 import java.io.IOException;
030 import java.io.InputStream;
031 import java.util.ArrayList;
032 import java.util.LinkedList;
033 import java.util.List;
034 import java.util.logging.Level;
035 import java.util.logging.Logger;
036
037 public class Importer implements FileSystem {
038
039 /** . */
040 private static final Logger log = Logger.getLogger(Importer.class.getName());
041
042 /** . */
043 private final ContentHandler handler;
044
045 /** . */
046 private final LinkedList<EndElement> stack;
047
048 /** . */
049 private final List<String> prefixes;
050
051 /** . */
052 private final DefaultHandler attributesHandler = new DefaultHandler() {
053
054 @Override
055 public void startPrefixMapping(String prefix, String uri) throws SAXException {
056 if (stack.isEmpty()) {
057 log.log(Level.FINE, "Adding prefix mapping " + prefix + " for " + uri);
058 handler.startPrefixMapping(prefix, uri);
059 prefixes.add(prefix);
060 }
061 }
062
063 @Override
064 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
065 log.log(Level.FINE, "Creating element " + qName);
066 handler.startElement(uri, localName, qName, attributes);
067 stack.addLast(new EndElement(uri, localName, qName));
068 }
069 };
070
071 public Importer(ContentHandler handler) {
072 this.handler = handler;
073 this.stack = new LinkedList<EndElement>();
074 this.prefixes = new ArrayList<String>();
075 }
076
077 public void beginDirectory(String directoryName) throws IOException {
078 }
079
080 public void file(String fileName, int length, InputStream data) throws IOException {
081 try {
082 SAXParserFactory factory = SAXParserFactory.newInstance();
083 factory.setNamespaceAware(true);
084 factory.setValidating(true);
085 SAXParser parser = factory.newSAXParser();
086 parser.parse(data, attributesHandler);
087 }
088 catch (Exception e) {
089 Safe.rethrow(IOException.class, e);
090 }
091 }
092
093 public void endDirectory(String directoryName) throws IOException {
094 try {
095 EndElement end = stack.removeLast();
096 handler.endElement(end.uri, end.localName, end.qName);
097 if (stack.isEmpty()) {
098 for (String prefix : prefixes) {
099 log.log(Level.FINE, "Removing prefix mapping " + prefix);
100 handler.endPrefixMapping(prefix);
101 }
102 prefixes.clear();
103 }
104 }
105 catch (Exception e) {
106 Safe.rethrow(IOException.class, e);
107 }
108 }
109
110 private static class EndElement {
111
112 /** . */
113 private final String uri;
114
115 /** . */
116 private final String localName;
117
118 /** . */
119 private final String qName;
120
121 private EndElement(String uri, String localName, String qName) {
122 this.uri = uri;
123 this.localName = localName;
124 this.qName = qName;
125 }
126 }
127 }
128