1 package com.indexdata.mkjsf.pazpar2.data;
\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
10 import javax.xml.parsers.ParserConfigurationException;
\r
11 import javax.xml.parsers.SAXParser;
\r
12 import javax.xml.parsers.SAXParserFactory;
\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
21 import com.indexdata.mkjsf.pazpar2.ClientCommandResponse;
\r
22 import com.indexdata.mkjsf.pazpar2.data.sp.AuthResponse;
\r
23 import com.indexdata.mkjsf.pazpar2.data.sp.CategoriesResponse;
\r
24 import com.indexdata.mkjsf.pazpar2.data.sp.TargetCategory;
\r
27 * Parses the XML stored in ClientCommandResponses and builds ResponseDataObjects from it.
\r
29 * @author Niels Erik
\r
32 public class ResponseParser extends DefaultHandler {
\r
34 private XMLReader xmlReader = null;
\r
35 private ResponseDataObject currentElement = null;
\r
36 private Stack<ResponseDataObject> dataElements = new Stack<ResponseDataObject>();
\r
37 private ResponseDataObject result = null;
\r
38 private String xml = null;
\r
39 private static Logger logger = Logger.getLogger(ResponseParser.class);
\r
41 public static List<String> docTypes = Arrays.asList( "bytarget","termlist","show","stat","record","search","init","info",
\r
42 /* SP extras */ "auth", "categories" );
\r
44 public ResponseParser() {
\r
47 } catch (ParserConfigurationException e) {
\r
48 // TODO Auto-generated catch block
\r
49 e.printStackTrace();
\r
50 } catch (SAXException e) {
\r
51 // TODO Auto-generated catch block
\r
52 e.printStackTrace();
\r
56 public static ResponseParser getParser() {
\r
57 return new ResponseParser();
\r
60 private void initSax() throws ParserConfigurationException, SAXException {
\r
61 SAXParserFactory spf = SAXParserFactory.newInstance();
\r
62 spf.setNamespaceAware(true);
\r
63 SAXParser saxParser = spf.newSAXParser();
\r
64 xmlReader = saxParser.getXMLReader();
\r
65 xmlReader.setContentHandler(this);
\r
69 * Parses a Pazpar2 XML response -- or an error response as XML -- and produces a
\r
70 * ResponseDataObject object, i.e. a 'show' object
\r
72 * @param response XML response string from Pazpar2
\r
73 * @return Response data object
\r
75 public ResponseDataObject getDataObject (ClientCommandResponse response) {
\r
76 this.xml = response.getResponseString();
\r
78 xmlReader.parse(new InputSource(new ByteArrayInputStream(response.getResponseToParse())));
\r
79 } catch (UnsupportedEncodingException e) {
\r
80 e.printStackTrace();
\r
81 } catch (IOException e) {
\r
82 e.printStackTrace();
\r
83 } catch (SAXException e) {
\r
84 e.printStackTrace();
\r
90 * Receive notification at the start of element
\r
94 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
\r
95 if (localName.equals("init")) {
\r
96 currentElement = new InitResponse();
\r
97 } else if (localName.equals("search")) {
\r
98 currentElement = new SearchResponse();
\r
99 } else if (localName.equals("show")) {
\r
100 currentElement = new ShowResponse();
\r
101 } else if (localName.equals("hit")) {
\r
102 currentElement = new Hit();
\r
103 } else if (localName.equals("location")) {
\r
104 currentElement = new Location();
\r
105 } else if (localName.equals("record")) {
\r
106 currentElement = new RecordResponse();
\r
107 } else if (localName.equals("bytarget")) {
\r
108 currentElement = new ByTargetResponse();
\r
109 } else if (localName.equals("target")) {
\r
110 currentElement = new Target();
\r
111 } else if (localName.equals("stat")) {
\r
112 currentElement = new StatResponse();
\r
113 } else if (localName.equals("termlist")) {
\r
114 currentElement = new TermListsResponse();
\r
115 } else if (localName.equals("list")) {
\r
116 currentElement = new TermListResponse();
\r
117 ((TermListResponse)currentElement).setName(atts.getValue("name"));
\r
118 ((TermListsResponse)dataElements.peek()).addTermList((TermListResponse)currentElement);
\r
119 } else if (localName.equals("term")) {
\r
120 if (dataElements.peek().getAttribute("name").equals("xtargets")) {
\r
121 currentElement = new TermXTargetResponse();
\r
123 currentElement = new TermResponse();
\r
125 ((TermListResponse)dataElements.peek()).addTerm((TermResponse)currentElement);
\r
126 } else if (localName.equals("info")) {
\r
127 currentElement = new InfoResponse();
\r
128 } else if (localName.equals("version") && dataElements.peek().getType().equals("info")) {
\r
129 currentElement = new Pazpar2VersionResponse();
\r
130 } else if (localName.equals("applicationerror")) {
\r
131 currentElement = new CommandError();
\r
132 } else if (localName.equals("error") && dataElements.peek().getType().equals("applicationerror")) {
\r
133 currentElement = new ServiceError();
\r
134 // Service Proxy extras
\r
135 } else if (localName.equals("auth")) {
\r
136 currentElement = new AuthResponse();
\r
137 } else if (localName.equals("categories")) {
\r
138 currentElement = new CategoriesResponse();
\r
139 } else if (localName.equals("category") && dataElements.peek().getType().equals("categories")) {
\r
140 currentElement = new TargetCategory();
\r
143 currentElement = new ResponseDataObject();
\r
145 currentElement.setType(localName);
\r
146 for (int i=0; i< atts.getLength(); i++) {
\r
147 currentElement.setAttribute(atts.getLocalName(i), atts.getValue(i));
\r
149 if (!docTypes.contains(localName)) {
\r
150 if (dataElements.size() == 0) {
\r
151 logger.info("Encountered unknown top level element [" + localName + "]. Creating generic data object.");
\r
152 currentElement.setType(localName);
\r
154 dataElements.peek().addElement(localName, currentElement);
\r
157 if (this.xml != null) { // Store XML for doc level elements
\r
158 currentElement.setXml(xml);
\r
161 dataElements.push(currentElement);
\r
165 public void characters(char[] ch, int start, int length) throws SAXException {
\r
166 String data = new String(ch, start, length);
\r
167 dataElements.peek().appendContent(data);
\r
171 public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
\r
172 if (dataElements.size()==1) {
\r
173 result = dataElements.pop();
\r
175 dataElements.pop();
\r