View Javadoc
1   /*
2    * Copyright (c) 2013, Dienst Landelijk Gebied - Ministerie van Economische Zaken
3    *
4    * Gepubliceerd onder de BSD 2-clause licentie,
5    * zie https://github.com/MinELenI/CBSviewer/blob/master/LICENSE.md voor de volledige licentie.
6    */
7   package nl.mineleni.openls.parser;
8   
9   import java.io.IOException;
10  import java.io.StringReader;
11  
12  import nl.mineleni.openls.databinding.gml.Point;
13  import nl.mineleni.openls.databinding.gml.Pos;
14  import nl.mineleni.openls.databinding.openls.Address;
15  import nl.mineleni.openls.databinding.openls.Building;
16  import nl.mineleni.openls.databinding.openls.GeocodeResponse;
17  import nl.mineleni.openls.databinding.openls.GeocodeResponseList;
18  import nl.mineleni.openls.databinding.openls.GeocodedAddress;
19  import nl.mineleni.openls.databinding.openls.Place;
20  import nl.mineleni.openls.databinding.openls.PostalCode;
21  import nl.mineleni.openls.databinding.openls.Street;
22  import nl.mineleni.openls.databinding.openls.StreetAddress;
23  
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  import org.xml.sax.Attributes;
27  import org.xml.sax.InputSource;
28  import org.xml.sax.SAXException;
29  
30  /**
31   * The Class OpenLSGeocodeResponseParser.
32   *
33   * @since 1.7
34   */
35  public class OpenLSGeocodeResponseParser extends AbstractOpenLSParser {
36  
37  	/** logger. */
38  	private static final Logger LOGGER = LoggerFactory
39  			.getLogger(OpenLSGeocodeResponseParser.class);
40  
41  	/*
42  	 * (non-Javadoc)
43  	 * 
44  	 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
45  	 * java.lang.String, java.lang.String)
46  	 */
47  	@Override
48  	public void endElement(final String uri, final String localName,
49  			final String qName) throws SAXException {
50  		final String[] nsName = qName.split(":");
51  		String eName = "";
52  		if (nsName.length > 1) {
53  			eName = nsName[1];
54  		} else {
55  			eName = nsName[0];
56  		}
57  		switch (eName.toLowerCase()) {
58  		case "geocoderesponselist":
59  			final GeocodeResponseList gcResList = (GeocodeResponseList) (this.objStack
60  					.pop());
61  			if (this.objStack.peek().getClass() == GeocodeResponse.class) {
62  				((GeocodeResponse) (this.objStack.peek()))
63  				.addGeocodeResponseList(gcResList);
64  			}
65  			break;
66  		case "geocodedaddress":
67  			final GeocodedAddress gcaddress = (GeocodedAddress) (this.objStack
68  					.pop());
69  			if (this.objStack.peek().getClass() == GeocodeResponseList.class) {
70  				((GeocodeResponseList) (this.objStack.peek()))
71  				.addGeocodedAddress(gcaddress);
72  			}
73  			break;
74  		case "point":
75  			final Point point = (Point) (this.objStack.pop());
76  			if (this.objStack.peek().getClass() == GeocodedAddress.class) {
77  				((GeocodedAddress) (this.objStack.peek())).setPoint(point);
78  			}
79  			break;
80  		case "pos":
81  			final Pos pos = (Pos) (this.objStack.pop());
82  			pos.setXY(this.eValBuf.toString());
83  			if (this.objStack.peek().getClass() == Point.class) {
84  				((Point) (this.objStack.peek())).addPos(pos);
85  			}
86  			break;
87  		case "address":
88  			final Address address = (Address) (this.objStack.pop());
89  			if (this.objStack.peek().getClass() == GeocodedAddress.class) {
90  				((GeocodedAddress) (this.objStack.peek())).setAddress(address);
91  			}
92  			break;
93  		case "streetaddress":
94  			final StreetAddress streetaddress = (StreetAddress) (this.objStack
95  					.pop());
96  			if (this.objStack.peek().getClass() == Address.class) {
97  				((Address) (this.objStack.peek()))
98  				.setStreetAddress(streetaddress);
99  			}
100 			break;
101 		case "building":
102 			final Building building = (Building) (this.objStack.pop());
103 			if (this.objStack.peek().getClass() == StreetAddress.class) {
104 				((StreetAddress) (this.objStack.peek())).setBuilding(building);
105 			}
106 			break;
107 		case "street":
108 			final Street street = (Street) (this.objStack.pop());
109 			street.setStreet(this.eValBuf.toString());
110 			if (this.objStack.peek().getClass() == StreetAddress.class) {
111 				((StreetAddress) (this.objStack.peek())).setStreet(street);
112 			}
113 			break;
114 		case "place":
115 			final Place place = (Place) (this.objStack.pop());
116 			place.setPlace(this.eValBuf.toString());
117 			if (this.objStack.peek().getClass() == Address.class) {
118 				((Address) (this.objStack.peek())).addPlace(place);
119 			}
120 			break;
121 		case "postalcode":
122 			final PostalCode pc = (PostalCode) (this.objStack.pop());
123 			pc.setPostalCode(this.eValBuf.toString());
124 			if (this.objStack.peek().getClass() == Address.class) {
125 				((Address) (this.objStack.peek())).setPostalCode(pc);
126 			}
127 			break;
128 		default:
129 			return;
130 		}
131 	}
132 
133 	/**
134 	 * Gets the geocode response.
135 	 *
136 	 * @return the geocode response
137 	 */
138 	public GeocodeResponse getGeocodeResponse() {
139 		GeocodeResponse geocodeResponse = null;
140 		if ((this.objStack.firstElement() != null)
141 				&& (this.objStack.firstElement().getClass() == GeocodeResponse.class)) {
142 			geocodeResponse = (GeocodeResponse) this.objStack.firstElement();
143 		}
144 		return geocodeResponse;
145 	}
146 
147 	/**
148 	 * Parses the open ls response.
149 	 *
150 	 * @param data
151 	 *            the data which is an OpenLS response xml document
152 	 * @return the geocode response object, will return null if parsing the data
153 	 *         failed
154 	 */
155 	public GeocodeResponse parseOpenLSResponse(final String data) {
156 		this.objStack.clear();
157 		try {
158 			this.parser.parse(new InputSource(new StringReader(data)), this);
159 		} catch (final SAXException | IOException e) {
160 			LOGGER.error("OpenLS response XML verwerken is mislukt: " + data
161 					+ ": ", e);
162 		}
163 		return this.getGeocodeResponse();
164 	}
165 
166 	/*
167 	 * (non-Javadoc)
168 	 * 
169 	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
170 	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
171 	 */
172 	@Override
173 	public void startElement(final String uri, final String localName,
174 			final String qName, final Attributes attributes)
175 					throws SAXException {
176 		this.eValBuf = new StringBuffer();
177 		final String[] nsName = qName.split(":");
178 		String eName = nsName[0];
179 		if (nsName.length > 1) {
180 			eName = nsName[1];
181 		}
182 		switch (eName.toLowerCase()) {
183 		case "geocoderesponse":
184 			this.objStack.push(new GeocodeResponse());
185 			break;
186 		case "geocoderesponselist":
187 			final GeocodeResponseList gcResList = new GeocodeResponseList();
188 			this.objStack.push(gcResList);
189 			for (int i = 0; i < attributes.getLength(); i++) {
190 				final String key = attributes.getQName(i);
191 				final String value = attributes.getValue(i);
192 				if (key.equalsIgnoreCase("numberOfGeocodedAddresses")) {
193 					final int val = Integer.parseInt(value);
194 					gcResList.setNumberOfGeocodedAddresses(val);
195 				}
196 			}
197 			break;
198 		case "geocodedaddress":
199 			this.objStack.push(new GeocodedAddress());
200 			break;
201 		case "point":
202 			final Point point = new Point();
203 			this.objStack.push(point);
204 			for (int i = 0; i < attributes.getLength(); i++) {
205 				final String key = attributes.getQName(i);
206 				final String value = attributes.getValue(i);
207 				if (key.equalsIgnoreCase("srsName")) {
208 					point.setSrsName(value);
209 				}
210 			}
211 			break;
212 		case "pos":
213 			final Pos pos = new Pos();
214 			this.objStack.push(pos);
215 			for (int i = 0; i < attributes.getLength(); i++) {
216 				final String key = attributes.getQName(i);
217 				final String value = attributes.getValue(i);
218 				if (key.equalsIgnoreCase("dimension")) {
219 					pos.setDimension(Integer.parseInt(value));
220 				}
221 			}
222 			break;
223 		case "address":
224 			final Address address = new Address();
225 			this.objStack.push(address);
226 			for (int i = 0; i < attributes.getLength(); i++) {
227 				final String key = attributes.getQName(i);
228 				final String value = attributes.getValue(i);
229 				if (key.equalsIgnoreCase("countryCode")) {
230 					address.setCountryCode(value);
231 				}
232 			}
233 			break;
234 		case "streetaddress":
235 			this.objStack.push(new StreetAddress());
236 			break;
237 		case "building":
238 			final Building building = new Building();
239 			this.objStack.push(building);
240 			for (int i = 0; i < attributes.getLength(); i++) {
241 				final String key = attributes.getQName(i);
242 				final String value = attributes.getValue(i);
243 				if (key.equalsIgnoreCase("number")) {
244 					building.setNumber(value);
245 				}
246 			}
247 			break;
248 		case "street":
249 			this.objStack.push(new Street());
250 			break;
251 		case "place":
252 			final Place place = new Place();
253 			this.objStack.push(place);
254 			for (int i = 0; i < attributes.getLength(); i++) {
255 				final String key = attributes.getQName(i);
256 				final String value = attributes.getValue(i);
257 				if (key.equalsIgnoreCase("type")) {
258 					place.setType(value);
259 				}
260 			}
261 			break;
262 		case "postalcode":
263 			this.objStack.push(new PostalCode());
264 			break;
265 		default:
266 			return;
267 		}
268 	}
269 }