View Javadoc
1   /*
2    * Copyright (c) 2013-2014, 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.Place;
17  import nl.mineleni.openls.databinding.openls.PostalCode;
18  import nl.mineleni.openls.databinding.openls.ReverseGeocodeResponse;
19  import nl.mineleni.openls.databinding.openls.ReverseGeocodedLocation;
20  import nl.mineleni.openls.databinding.openls.SearchCentreDistance;
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   * Parse reverse geocode response.
32   *
33   * @author prinsmc
34   *
35   */
36  public class OpenLSReverseGeocodeResponseParser extends AbstractOpenLSParser {
37  	/** logger. */
38  	private static final Logger LOGGER = LoggerFactory
39  			.getLogger(OpenLSReverseGeocodeResponseParser.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  
58  		switch (eName.toLowerCase()) {
59  		case "reversegeocoderesponse":
60  			break;
61  		case "reversegeocodedlocation":
62  			final ReverseGeocodedLocation loc = (ReverseGeocodedLocation) this.objStack
63  			.pop();
64  			if (this.objStack.peek().getClass() == ReverseGeocodeResponse.class) {
65  				((ReverseGeocodeResponse) (this.objStack.peek()))
66  				.setReverseGeocodedLocation(loc);
67  			}
68  			break;
69  		case "point":
70  			final Point point = (Point) (this.objStack.pop());
71  			if (this.objStack.peek().getClass() == ReverseGeocodedLocation.class) {
72  				((ReverseGeocodedLocation) (this.objStack.peek()))
73  				.setPoint(point);
74  			}
75  			break;
76  		case "pos":
77  			final Pos pos = (Pos) (this.objStack.pop());
78  			pos.setXY(this.eValBuf.toString());
79  			if (this.objStack.peek().getClass() == Point.class) {
80  				((Point) (this.objStack.peek())).addPos(pos);
81  			}
82  			break;
83  		case "address":
84  			final Address address = (Address) (this.objStack.pop());
85  			if (this.objStack.peek().getClass() == ReverseGeocodedLocation.class) {
86  				((ReverseGeocodedLocation) (this.objStack.peek()))
87  				.setAddress(address);
88  			}
89  			break;
90  		case "streetaddress":
91  			final StreetAddress streetaddress = (StreetAddress) (this.objStack
92  					.pop());
93  			if (this.objStack.peek().getClass() == Address.class) {
94  				((Address) (this.objStack.peek()))
95  				.setStreetAddress(streetaddress);
96  			}
97  			break;
98  		case "building":
99  			final Building building = (Building) (this.objStack.pop());
100 			if (this.objStack.peek().getClass() == StreetAddress.class) {
101 				((StreetAddress) (this.objStack.peek())).setBuilding(building);
102 			}
103 			break;
104 		case "street":
105 			final Street street = (Street) (this.objStack.pop());
106 			street.setStreet(this.eValBuf.toString());
107 			if (this.objStack.peek().getClass() == StreetAddress.class) {
108 				((StreetAddress) (this.objStack.peek())).setStreet(street);
109 			}
110 			break;
111 		case "place":
112 			final Place place = (Place) (this.objStack.pop());
113 			place.setPlace(this.eValBuf.toString());
114 			if (this.objStack.peek().getClass() == Address.class) {
115 				((Address) (this.objStack.peek())).addPlace(place);
116 			}
117 			break;
118 		case "postalcode":
119 			final PostalCode pc = (PostalCode) (this.objStack.pop());
120 			pc.setPostalCode(this.eValBuf.toString());
121 			if (this.objStack.peek().getClass() == Address.class) {
122 				((Address) (this.objStack.peek())).setPostalCode(pc);
123 			}
124 			break;
125 		case "searchcentredistance":
126 			final SearchCentreDistance dist = (SearchCentreDistance) (this.objStack
127 					.pop());
128 			if (this.objStack.peek().getClass() == ReverseGeocodedLocation.class) {
129 				((ReverseGeocodedLocation) (this.objStack.peek()))
130 				.setSearchCentreDistance(dist);
131 			}
132 			break;
133 		default:
134 			break;
135 		}
136 	}
137 
138 	/**
139 	 * Gets the reverse geocode response.
140 	 *
141 	 * @return the reverse geocode response
142 	 */
143 	public ReverseGeocodeResponse getReverseGeocodeResponse() {
144 		ReverseGeocodeResponse geocodeResponse = null;
145 		if ((this.objStack.firstElement() != null)
146 				&& (this.objStack.firstElement().getClass() == ReverseGeocodeResponse.class)) {
147 			geocodeResponse = (ReverseGeocodeResponse) this.objStack
148 					.firstElement();
149 		}
150 		// LOGGER.debug(geocodeResponse.toXML());
151 		return geocodeResponse;
152 	}
153 
154 	/**
155 	 * Parses the open ls reverse geocode response.
156 	 *
157 	 * @param data
158 	 *            the data which is an OpenLS response xml document
159 	 * @return the geocode response object, will return null if parsing the data
160 	 *         failed
161 	 */
162 	public ReverseGeocodeResponse parseOpenLSReverseGeocodeResponse(
163 			final String data) {
164 		this.objStack.clear();
165 		try {
166 			final InputSource input = new InputSource(new StringReader(data));
167 			input.setEncoding("UTF-8");
168 			this.parser.parse(input, this);
169 		} catch (final SAXException | IOException e) {
170 			LOGGER.error("OpenLS response XML verwerken is mislukt: " + data
171 					+ ": ", e);
172 		}
173 		return this.getReverseGeocodeResponse();
174 	}
175 
176 	/*
177 	 * (non-Javadoc)
178 	 * 
179 	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
180 	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
181 	 */
182 	@Override
183 	public void startElement(final String uri, final String localName,
184 			final String qName, final Attributes attributes)
185 					throws SAXException {
186 		this.eValBuf = new StringBuffer();
187 		final String[] nsName = qName.split(":");
188 		String eName = nsName[0];
189 		if (nsName.length > 1) {
190 			eName = nsName[1];
191 		}
192 
193 		switch (eName.toLowerCase()) {
194 		case "reversegeocoderesponse":
195 			this.objStack.push(new ReverseGeocodeResponse());
196 			break;
197 		case "reversegeocodedlocation":
198 			this.objStack.push(new ReverseGeocodedLocation());
199 			break;
200 		case "point":
201 			final Point point = new Point();
202 			for (int i = 0; i < attributes.getLength(); i++) {
203 				final String key = attributes.getQName(i);
204 				final String value = attributes.getValue(i);
205 				if (key.equalsIgnoreCase("srsName")) {
206 					point.setSrsName(value);
207 				}
208 			}
209 			this.objStack.push(point);
210 			break;
211 		case "pos":
212 			final Pos pos = new Pos();
213 			for (int i = 0; i < attributes.getLength(); i++) {
214 				final String key = attributes.getQName(i);
215 				final String value = attributes.getValue(i);
216 				if (key.equalsIgnoreCase("dimension")) {
217 					pos.setDimension(Integer.parseInt(value));
218 				}
219 			}
220 			this.objStack.push(pos);
221 			break;
222 		case "address":
223 			final Address addr = new Address();
224 			for (int i = 0; i < attributes.getLength(); i++) {
225 				final String key = attributes.getQName(i);
226 				final String value = attributes.getValue(i);
227 				if (key.equalsIgnoreCase("countryCode")) {
228 					addr.setCountryCode(value);
229 				}
230 			}
231 			this.objStack.push(addr);
232 			break;
233 		case "streetaddress":
234 			final StreetAddress strAddr = new StreetAddress();
235 			this.objStack.push(strAddr);
236 			break;
237 		case "street":
238 			final Street street = new Street();
239 			this.objStack.push(street);
240 			break;
241 		case "place":
242 			final Place place = new Place();
243 			for (int i = 0; i < attributes.getLength(); i++) {
244 				final String key = attributes.getQName(i);
245 				final String value = attributes.getValue(i);
246 				if (key.equalsIgnoreCase("type")) {
247 					place.setType(value);
248 				}
249 			}
250 			this.objStack.push(place);
251 			break;
252 		case "searchcentredistance":
253 			final SearchCentreDistance dist = new SearchCentreDistance();
254 			this.objStack.push(dist);
255 			for (int i = 0; i < attributes.getLength(); i++) {
256 				final String key = attributes.getQName(i);
257 				final String value = attributes.getValue(i);
258 				if (key.equalsIgnoreCase("uom")) {
259 					dist.setUom(value);
260 				}
261 				if (key.equalsIgnoreCase("value")) {
262 					dist.setValue(Double.parseDouble(value));
263 				}
264 				if (key.equalsIgnoreCase("accuracy")) {
265 					dist.setAccuracy(Double.parseDouble(value));
266 				}
267 			}
268 			break;
269 		default:
270 			LOGGER.warn("Onbekend element '" + eName + "' wordt genegeerd.");
271 			break;
272 		}
273 	}
274 
275 }