Renames data classes that are no longer pz2 only
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / mkjsf / pazpar2 / data / ResponseParser.java
1 package com.indexdata.mkjsf.pazpar2.data;\r
2 \r
3 import java.io.ByteArrayInputStream;\r
4 import java.io.IOException;\r
5 import java.io.UnsupportedEncodingException;\r
6 import java.util.Arrays;\r
7 import java.util.List;\r
8 import java.util.Stack;\r
9 \r
10 import javax.xml.parsers.ParserConfigurationException;\r
11 import javax.xml.parsers.SAXParser;\r
12 import javax.xml.parsers.SAXParserFactory;\r
13 \r
14 import org.apache.log4j.Logger;\r
15 import org.xml.sax.Attributes;\r
16 import org.xml.sax.InputSource;\r
17 import org.xml.sax.SAXException;\r
18 import org.xml.sax.XMLReader;\r
19 import org.xml.sax.helpers.DefaultHandler;\r
20 \r
21 import com.indexdata.mkjsf.pazpar2.data.ByTarget;\r
22 import com.indexdata.mkjsf.pazpar2.data.Hit;\r
23 import com.indexdata.mkjsf.pazpar2.data.Location;\r
24 import com.indexdata.mkjsf.pazpar2.data.ResponseDataObject;\r
25 import com.indexdata.mkjsf.pazpar2.data.RecordResponse;\r
26 import com.indexdata.mkjsf.pazpar2.data.ShowResponse;\r
27 import com.indexdata.mkjsf.pazpar2.data.StatResponse;\r
28 import com.indexdata.mkjsf.pazpar2.data.Target;\r
29 import com.indexdata.mkjsf.pazpar2.data.TermListResponse;\r
30 import com.indexdata.mkjsf.pazpar2.data.TermListsResponse;\r
31 import com.indexdata.mkjsf.pazpar2.data.TermResponse;\r
32 import com.indexdata.mkjsf.pazpar2.data.TermXTargetResponse;\r
33 \r
34 public class ResponseParser extends DefaultHandler {\r
35 \r
36   private XMLReader xmlReader = null;\r
37   private ResponseDataObject currentElement = null;\r
38   private Stack<ResponseDataObject> dataElements = new Stack<ResponseDataObject>();\r
39   private ResponseDataObject result = null;\r
40   private String xml = null;\r
41   private static Logger logger = Logger.getLogger(ResponseParser.class);\r
42 \r
43   public static final List<String> docTypes = \r
44       Arrays.asList("bytarget","termlist","show","stat","record","search");\r
45   \r
46   public ResponseParser() {    \r
47     try {\r
48       initSax();\r
49     } catch (ParserConfigurationException e) {\r
50       // TODO Auto-generated catch block\r
51       e.printStackTrace();\r
52     } catch (SAXException e) {\r
53       // TODO Auto-generated catch block\r
54       e.printStackTrace();\r
55     }\r
56   }\r
57   \r
58   public static ResponseParser getParser() {\r
59     return new ResponseParser();\r
60   }\r
61   \r
62   private void initSax() throws ParserConfigurationException, SAXException {\r
63     SAXParserFactory spf = SAXParserFactory.newInstance();\r
64     spf.setNamespaceAware(true);\r
65     SAXParser saxParser = spf.newSAXParser();\r
66     xmlReader = saxParser.getXMLReader();\r
67     xmlReader.setContentHandler(this);         \r
68   }\r
69   \r
70   /**\r
71    * Parses a Pazpar2 XML response -- or an error response as XML -- and produces a \r
72    * ResponseDataObject object, i.e. a 'show' object\r
73    * \r
74    * @param response XML response string from Pazpar2\r
75    * @return Response data object\r
76    */\r
77   public ResponseDataObject getDataObject (String response) {\r
78     this.xml = response;\r
79     try {      \r
80       xmlReader.parse(new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8"))));\r
81     } catch (UnsupportedEncodingException e) {\r
82       // TODO Auto-generated catch block\r
83       e.printStackTrace();      \r
84     } catch (IOException e) {\r
85       // TODO Auto-generated catch block\r
86       e.printStackTrace();\r
87     } catch (SAXException e) {\r
88       // TODO Auto-generated catch block\r
89       e.printStackTrace();      \r
90     }\r
91     return result;\r
92   }\r
93 \r
94   /** \r
95    * Receive notification at the start of element \r
96    * \r
97    */\r
98   @Override\r
99   public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {\r
100     if (localName.equals("show")) {\r
101       currentElement = new ShowResponse();      \r
102     } else if (localName.equals("hit")) {\r
103       currentElement = new Hit();\r
104     } else if (localName.equals("location")) {\r
105       currentElement = new Location();\r
106     } else if (localName.equals("bytarget")) {\r
107       currentElement = new ByTarget();      \r
108     } else if (localName.equals("target")) {\r
109       currentElement = new Target();\r
110     } else if (localName.equals("stat")) {\r
111       currentElement = new StatResponse();      \r
112     } else if (localName.equals("termlist")) {\r
113       currentElement = new TermListsResponse();      \r
114     } else if (localName.equals("list")) {\r
115       currentElement = new TermListResponse();\r
116       ((TermListResponse)currentElement).setName(atts.getValue("name"));\r
117       ((TermListsResponse)dataElements.peek()).addTermList((TermListResponse)currentElement);\r
118     } else if (localName.equals("term")) {\r
119       if (dataElements.peek().getAttribute("name").equals("xtargets")) {\r
120         currentElement = new TermXTargetResponse();        \r
121       } else {\r
122         currentElement = new TermResponse();\r
123       }\r
124       ((TermListResponse)dataElements.peek()).addTerm((TermResponse)currentElement);\r
125     } else if (localName.equals("record")) {\r
126       currentElement = new RecordResponse();      \r
127     } else if (localName.equals("search")) {\r
128       currentElement = new SearchResponse();\r
129     } else if (localName.equals("applicationerror")) {\r
130       currentElement = new CommandError();\r
131     } else if (localName.equals("error") && dataElements.peek().getType().equals("applicationerror")) {\r
132       currentElement = new Pazpar2Error();     \r
133     } else {\r
134       currentElement = new ResponseDataObject();\r
135     }\r
136     currentElement.setType(localName);\r
137     for (int i=0; i< atts.getLength(); i++) {\r
138        currentElement.setAttribute(atts.getLocalName(i), atts.getValue(i));\r
139     }    \r
140     if (!docTypes.contains(localName)) {\r
141       if (dataElements.size() == 0) {\r
142         logger.info("Encountered unknown top level element [" + localName + "]. Creating generic data object.");\r
143         currentElement.setType(localName);\r
144       } else {\r
145         dataElements.peek().addElement(localName, currentElement);\r
146       }\r
147     }\r
148     if (this.xml != null) { // Store XML for doc level elements\r
149       currentElement.setXml(xml);\r
150       xml = null;\r
151     }\r
152     dataElements.push(currentElement);    \r
153   }\r
154  \r
155   @Override\r
156   public void characters(char[] ch, int start, int length) throws SAXException {\r
157     String data = new String(ch, start, length);        \r
158     dataElements.peek().appendContent(data);    \r
159   }\r
160   \r
161   @Override\r
162   public void endElement(String namespaceURI, String localName, String qName) throws SAXException {\r
163     if (dataElements.size()==1) {\r
164       result = dataElements.pop();\r
165     } else {\r
166       dataElements.pop();\r
167     }\r
168   }\r
169 }\r