001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.commons.io.res.type.s3;
020
021import java.io.IOException;
022import java.io.InputStream;
023import java.io.Reader;
024
025import lucee.loader.util.Util;
026import lucee.runtime.text.xml.XMLUtil;
027
028import org.xml.sax.Attributes;
029import org.xml.sax.InputSource;
030import org.xml.sax.SAXException;
031import org.xml.sax.XMLReader;
032import org.xml.sax.helpers.DefaultHandler;
033
034/**
035 * Die Klasse TagLibFactory liest die XML Repraesentation einer TLD ein 
036 * und laedt diese in eine Objektstruktur. 
037 * Sie tut dieses mithilfe eines Sax Parser.
038 * Die Klasse kann sowohl einzelne Files oder gar ganze Verzeichnisse von TLD laden.
039 */
040public abstract class S3Factory extends DefaultHandler {
041        
042        public final static String DEFAULT_SAX_PARSER="org.apache.xerces.parsers.SAXParser";
043                
044        private XMLReader xmlReader;
045        
046        protected String inside;
047        protected StringBuffer content=new StringBuffer();
048
049        private boolean insideError;
050        private boolean insideMessage;
051
052
053
054        /**
055         * Privater Konstruktor, der als Eingabe die TLD als File Objekt erhaelt.
056         * @param saxParser String Klassenpfad zum Sax Parser.
057         * @param file File Objekt auf die TLD.
058         * @throws IOException 
059         * @throws SAXException 
060         */
061        public S3Factory() {
062                
063        }
064        
065        /**
066         * Generelle Initialisierungsmetode der Konstruktoren.
067         * @param saxParser String Klassenpfad zum Sax Parser.
068         * @param  is InputStream auf die TLD.
069         * @throws SAXException 
070         * @throws IOException 
071         */
072        protected void init(InputStream in) throws IOException, SAXException    {
073                Reader r=null;
074                try {
075                        InputSource is=new InputSource(in);
076                        xmlReader=XMLUtil.createXMLReader(DEFAULT_SAX_PARSER);
077                        xmlReader.setContentHandler(this);
078                        xmlReader.setErrorHandler(this);
079                        xmlReader.parse(is);
080                        
081                }
082                finally {
083                        Util.closeEL(r);
084                }
085    }
086
087        @Override
088        public final void startElement(String uri, String name, String qName, Attributes atts) {
089                inside=qName;
090
091                if(qName.equalsIgnoreCase("Error")) insideError=true;
092                if(qName.equalsIgnoreCase("Message")) insideMessage=true;
093                doStartElement(uri, name, qName, atts);
094        }
095        protected abstract void doStartElement(String uri, String name, String qName, Attributes atts);
096    
097        @Override
098        public final void endElement(String uri, String name, String qName) throws SAXException {
099                _setContent(content.toString().trim());
100                content=new StringBuffer();
101                inside="";
102
103                if(qName.equalsIgnoreCase("Error")) insideError=false;
104                if(qName.equalsIgnoreCase("Message")) insideMessage=false;
105                doEndElement(uri, name, qName);
106        }
107        
108        public abstract void doEndElement(String uri, String name, String qName) throws SAXException;
109        
110        
111    private void _setContent(String value) throws SAXException {
112        
113        if(insideError && insideMessage)        {
114                throw new SAXException(value);
115        }
116        setContent(value);
117        /*
118        <?xml version="1.0" encoding="UTF-8"?>
119                <Error>
120                        <Code>SignatureDoesNotMatch</Code>
121                        <Message>The request signature we calculated does not match the signature you provided. 
122                                Check your key and signing method.</Message>
123                        <RequestId>53DE01E3379AEF9F</RequestId>
124                        <SignatureProvided>CsJJe9qgVVxoOPyAZ48XhFd8VJs=</SignatureProvided>
125                        <StringToSignBytes>47 45 54 0a 0a 0a 57 65 64 2c 20 30 35 20 4d 61 72 20 32 30 30 38 20 31 31 3a 31 39 3a 34 33 20 47 4d 54 0a 2f</StringToSignBytes>
126                        <AWSAccessKeyId>03SG52G1QX3EVP5FEMG2</AWSAccessKeyId>
127                        <HostId>TFyQxYQuisdThJrENWZW7Q1yp5mbVabV8jGx6B0m9pB6dSG/AJhpCTEWnQpW/otb</HostId>
128                        <StringToSign>GET
129
130        */
131    }
132
133        protected abstract void setContent(String value) throws SAXException;
134
135        @Override
136        public void characters (char ch[], int start, int length)       {
137                content.append(new String(ch,start,length));
138        }
139}