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