001/*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.select;
017
018import org.apache.log4j.Logger;
019
020import java.io.*;
021import java.net.HttpURLConnection;
022import java.net.MalformedURLException;
023import java.net.URL;
024import java.net.UnknownHostException;
025
026public class CitationParser {
027
028    private static final String CITATION_PARSER_URL = "http://freecite.library.brown.edu/citations/create";
029    private URL citationParserURL;
030    private Writer outputStreamWriter;
031    private Reader reader;
032    private Logger LOG = org.apache.log4j.Logger.getLogger(CitationParser.class);
033
034    public boolean isConnectionAlive() {
035        try {
036            URL citationParserURL = getURLObject();
037            HttpURLConnection urlConnection = (HttpURLConnection) citationParserURL.openConnection();
038            urlConnection.setConnectTimeout(1000);
039            if (urlConnection != null) {
040                urlConnection.getInputStream();
041            }
042            return urlConnection != null;
043
044        } catch (IOException e) {
045            return false;
046        }
047    }
048
049    public String parse(String object) {
050        String parsedCitation = "";
051
052        HttpURLConnection urlConnection = null;
053        try {
054            URL citationParserURL = getURLObject();
055            urlConnection = (HttpURLConnection) citationParserURL.openConnection();
056            setUrlConnectionProperties(urlConnection);
057            readCitationParmameters(object, urlConnection);
058            parsedCitation = readResultsFromCitationParser(urlConnection);
059        } catch (FileNotFoundException e) {
060            LOG.error("Invalid Citation Parser URL (" + citationParserURL + " ): " + e);
061            throw new RuntimeException("Invalid Citation Parser URL (" + citationParserURL + " ): " + e, e);
062        } catch (UnknownHostException e) {
063            LOG.error("Invalid Citation Parser URL (" + citationParserURL + " ): " + e);
064            throw new RuntimeException("Invalid Citation Parser URL (" + citationParserURL + " ): " + e, e);
065        } catch (IOException e) {
066            if (e.getMessage().indexOf("504") != -1) {
067                LOG.error("Connection Timeout: (" + citationParserURL + " ): " + e);
068                throw new RuntimeException("Connection Timeout: (" + citationParserURL + " ): " + e, e);
069            } else {
070                LOG.error("Internal Server Error or Service Unavailable: (" + citationParserURL + " ): " + e);
071                throw new RuntimeException("Internal Server Error or Service Unavailable (" + citationParserURL + " ): " + e, e);
072            }
073        } catch (Exception ex) {
074            LOG.error("Connection error:unable to connect " + citationParserURL + " : " + ex);
075            throw new RuntimeException("Connection error:unable to connect " + citationParserURL + " : " + ex, ex);
076        } finally {
077            if (urlConnection != null) {
078                urlConnection.disconnect();
079            }
080        }
081
082        return parsedCitation;
083    }
084
085    private URL getURLObject() throws MalformedURLException {
086        if (null == citationParserURL) {
087            citationParserURL = new URL(CITATION_PARSER_URL);
088        }
089        return citationParserURL;
090    }
091
092    public void setCitationParserURL(URL citationParserURL) {
093        this.citationParserURL = citationParserURL;
094    }
095
096    private String readResultsFromCitationParser(HttpURLConnection urlConnection) throws Exception {
097        InputStream inputStream = urlConnection.getInputStream();
098        StringWriter stringWriter = new StringWriter();
099        String parsedCitation = "";
100        try {
101            reader = getInputStreamReader(inputStream);
102            pipe(reader, stringWriter);
103            if (LOG.isDebugEnabled()) {
104                LOG.debug("response--------->" + stringWriter.toString());
105            }
106            parsedCitation = stringWriter.toString();
107            reader.close();
108        } catch (IOException e) {
109            throw new Exception("IOException while reading response", e);
110        } finally {
111            if (inputStream != null) {
112                inputStream.close();
113            }
114        }
115        return parsedCitation;
116    }
117
118    private Reader getInputStreamReader(InputStream inputStream) {
119        //if (null == reader) { //Removed if condition because for the first time the object will be set here for the next time object will be in not null state wont set the object, but it will be in closed state, so each and every time this object needs to be initialized here.
120        reader = new InputStreamReader(inputStream);
121        //}
122        return reader;
123    }
124
125    private void readCitationParmameters(Object object, HttpURLConnection urlConnection) throws Exception {
126        Reader stringReader = new StringReader(object.toString());
127        OutputStream outputStream = urlConnection.getOutputStream();
128        try {
129            outputStreamWriter = getOutputStreamWriter(outputStream);
130            pipe(stringReader, outputStreamWriter);
131            outputStreamWriter.close();
132        } catch (IOException e) {
133            throw new Exception("IOException while posting stringReader", e);
134        } finally {
135            if (outputStream != null) {
136                outputStream.close();
137            }
138        }
139    }
140
141    public void setOutputStreamWriter(Writer outputStreamWriter) {
142        this.outputStreamWriter = outputStreamWriter;
143    }
144
145    public void setReader(Reader reader) {
146        this.reader = reader;
147    }
148
149    private Writer getOutputStreamWriter(OutputStream outputStream) throws UnsupportedEncodingException {
150        //if (null == outputStreamWriter) { //Removed if condition because for the first time the object will be set here for the next time object will be in not null state wont set the object, but it will be in closed state, so each and every time this object needs to be initialized here.
151        outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
152        //}
153        return outputStreamWriter;
154    }
155
156    private void setUrlConnectionProperties(HttpURLConnection urlConnection) {
157        urlConnection.setDoOutput(true);
158        urlConnection.setDoInput(true);
159        urlConnection.setRequestProperty("Accept", "text/xml");
160        // give it 5 seconds to connect normally - should never take that long.
161        urlConnection.setConnectTimeout(5000);
162    }
163
164    private void pipe(Reader reader, Writer writer) throws IOException {
165        char[] buf = new char[1024];
166        int read = 0;
167        while ((read = reader.read(buf)) >= 0) {
168            writer.write(buf, 0, read);
169        }
170        writer.flush();
171    }
172
173}