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