001    /*
002     * $RCSfile: RequestFactory.java,v $
003     *
004     * Created on August 26, 2003, 9:55 AM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2002-2006 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    
024    package gov.bnl.star.offline.scheduler.request;
025    
026    import gov.bnl.star.offline.scheduler.*;
027    import java.io.*;
028    import java.util.*;
029    import java.util.logging.*;
030    import java.util.logging.Level;
031    import org.apache.log4j.Logger;
032    import javax.xml.parsers.*;
033    import javax.xml.transform.*;
034    //import org.apache.xpath.*;
035    import org.w3c.dom.*;
036    import org.xml.sax.*;
037    import org.xml.sax.helpers.*;
038    
039    /**
040     *
041     * @author  carcassi
042     * @version $Revision: 1.8 $ $Date: 2006/11/21 00:41:31 $
043     */
044    public class RequestFactory {
045        static private Logger log = Logger.getLogger(RequestFactory.class.getName());
046        
047        /** Creates a new instance of RequestFactory */
048        public RequestFactory() {
049        }
050        
051        private static Map defaults = new Hashtable();
052        public static void setDefaults(Map defaults) {
053            RequestFactory.defaults = defaults;
054        }
055    
056        public static Request parseXML(String xmlFileName) {
057            log.debug("Start parsing request");
058    
059            InputStream xml = getInputStream(xmlFileName);
060            if (xml == null) {
061               log.debug("Can't open request file " + xmlFileName);
062               throw new RuntimeException("Can't open request file " +
063                   xmlFileName, null);
064            }
065            String xmls = getStreamAsString(xml);
066            return parseXMLString(xmls, xmlFileName);
067        }
068    
069        public static Request parseXMLString(String xmls, String xmlFileName) {
070    
071            SAXParserFactory factory = SAXParserFactory.newInstance();
072            SAXParser saxParser;
073            Request[] requests;
074    
075            factory.setValidating(true);
076    
077            try {
078                saxParser = factory.newSAXParser();
079            } catch (Throwable t) {
080                log.error("Exception creating SAX parser", t);
081                throw new RuntimeException("Exception creating SAX parser.\n" +
082                   t.getMessage(), t);
083            }
084    
085            log.debug("Parsing request type");
086    
087            RequestTypeHandler typeHandler = new RequestTypeHandler();
088    
089            try {
090                saxParser.parse(new ByteArrayInputStream(xmls.getBytes()), 
091                    typeHandler);
092            } catch (RequestTypeException x) { // expected exception
093            } catch (Exception e) {
094                log.fatal("Exception parsing request type", e);
095                throw new RuntimeException("Exception parsing request type.\n" +
096                   e.getMessage(), e);
097            }
098    
099            log.debug("Finished parsing request type");
100    
101            if (typeHandler.getRequestType() == RequestType.NONE) {
102                log.fatal("Request format not recognized");
103                throw new RuntimeException("Request format not recognized");
104            }
105    
106            // Perform XML schema validation
107            ValidateXMLSchema validator = new ValidateXMLSchema();
108            if (!validator.TestFile(xmls, typeHandler.getRequestType())) {
109                log.fatal("XML Schema validation failed");
110                throw new RuntimeException("XML Schema validation failed");
111            }
112    
113            RequestHandler handler = null;
114    
115            switch (typeHandler.getRequestType()) {
116                case RequestType.JDL:
117                    log.debug("Parsing JDL request");
118                    handler = new JDLHandler(xmlFileName);
119                    break;
120                case RequestType.RDL:
121                    log.debug("Parsing RDL request");
122                    handler = new RDLHandler(xmlFileName);
123                    break;
124                default: // should never get here
125                    break;
126            }
127    
128            handler.setDefaults(defaults);
129    
130            try {
131                // Parse the request
132                saxParser.parse(new ByteArrayInputStream(xmls.getBytes()), handler);
133            } catch (Throwable t) {
134                log.debug("Couldn't parse request", t);
135                throw new RuntimeException("Couldn't parse request.\n" +
136                        t.getMessage(), t);
137            }
138                                                                                    
139            requests = handler.getRequests();
140    
141            log.debug("Finished parsing request");
142    
143            if (requests.length == 0)
144                throw new RuntimeException("No valid request found in XML");
145    
146            return requests[0];
147        }
148    
149       /** Read request from file into InputStream
150        *
151        * @param fileName file to read
152        * @return InputStream for file
153        */
154        private static InputStream getInputStream(String fileName) {
155            InputStream is = null;
156            try {
157                is = new FileInputStream(fileName);
158            } catch (FileNotFoundException e) {
159                is = RequestFactory.class.getResourceAsStream(fileName);
160                if (is == null)
161                    log.fatal("Cannot find file "+fileName);
162            }
163            return is;
164        }
165                                                                                    
166       /** Read request from input stream into a String
167        *
168        * @param stream InputStream to read
169        * @return String with contents of input stream
170        */
171        private static String getStreamAsString(InputStream stream) {
172            // Read input stream into a String
173            int numRead;
174            int buffSize = 128;
175            byte buff[] = new byte[buffSize];
176            OutputStream oStream = new ByteArrayOutputStream(buffSize);
177    
178            try {
179                while ( (numRead = stream.read(buff) ) != -1)
180                    oStream.write(buff, 0, numRead);         
181            } catch (IOException e) {
182                log.fatal("Exception reading input", e);
183                throw new RuntimeException("Exception reading input.\n" +
184                   e.getMessage(), e);
185            }
186    
187            return oStream.toString(); 
188        }
189        
190        /** Tests the parser by analyzing a file and displaying the
191         * content of the Request list that the parser returned.
192         * @param args the name of the XML request file 
193         */
194        public static void main(String[] args) {
195            // Enabling logging to the finest degree
196            /*
197            Handler[] handlers = Logger.getLogger("").getHandlers();
198    
199            for (int index = 0; index < handlers.length; index++) {
200                handlers[index].setLevel(Level.FINEST);
201            }
202    
203            LogManager.getLogManager().getLogger("").setLevel(Level.FINEST);
204            */
205            // TODO: Code migration, the code is for multiple requests
206            try {
207            Request[] jobs = new Request[] {parseXML(args[0])};
208            System.out.println("" + jobs.length + " were found in the XML file");
209    
210            for (int nJob = 0; nJob < jobs.length; nJob++) {
211                System.out.println("Job number " + (nJob + 1));
212                System.out.println("Name : " + jobs[nJob].getName());
213                System.out.println("Description : " + jobs[nJob].getDescription());
214                System.out.println("User : " + jobs[nJob].getUsername());
215                System.out.println("Command : " + jobs[nJob].getCommand());
216                System.out.println("Standard in : " + jobs[nJob].getStdIn());
217                System.out.println("Standard out : " + jobs[nJob].getStdOut());
218    
219                System.out.println("Requested input file list:");
220    
221                List list = jobs[nJob].getInputList();
222                System.out.println("   Number of input : " + list.size());
223    
224                for (int nInput = 0; nInput < list.size(); nInput++) {
225                    System.out.println("   " + list.get(nInput));
226                }
227    
228                System.out.println("Requested output file list:");
229    
230                List oList = jobs[nJob].getOutputList();
231                System.out.println("   Number of output : " + oList.size());
232    
233                for (int nOutput = 0; nOutput < oList.size(); nOutput++) {
234                    System.out.println("   " + oList.get(nOutput));
235                }
236    
237            }
238            } catch (Exception e) {
239                System.out.println("Couldn't load");
240                e.printStackTrace();
241            }
242        }
243    }