1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package com.gisgraphy.domain.geoloc.service.geoloc;
24
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.io.UnsupportedEncodingException;
29 import java.io.Writer;
30 import java.util.ArrayList;
31 import java.util.List;
32
33 import javax.xml.bind.JAXBContext;
34 import javax.xml.bind.JAXBException;
35 import javax.xml.bind.Marshaller;
36
37 import net.sf.json.JSON;
38 import net.sf.json.JSONSerializer;
39 import net.sf.json.JsonConfig;
40 import net.sf.json.util.PropertyFilter;
41
42 import com.gisgraphy.domain.geoloc.service.ServiceException;
43 import com.gisgraphy.domain.geoloc.service.errors.UnsupportedFormatException;
44 import com.gisgraphy.domain.valueobject.Constants;
45 import com.gisgraphy.domain.valueobject.GeolocResultsDto;
46 import com.gisgraphy.domain.valueobject.GisgraphyServiceType;
47 import com.gisgraphy.domain.valueobject.Pagination;
48 import com.gisgraphy.domain.valueobject.StreetDistance;
49 import com.gisgraphy.domain.valueobject.StreetSearchResultsDto;
50 import com.gisgraphy.domain.valueobject.Output.OutputFormat;
51 import com.sun.syndication.feed.module.georss.GeoRSSModule;
52 import com.sun.syndication.feed.module.georss.gml.GMLModuleImpl;
53 import com.sun.syndication.feed.module.opensearch.OpenSearchModule;
54 import com.sun.syndication.feed.module.opensearch.impl.OpenSearchModuleImpl;
55 import com.sun.syndication.feed.synd.SyndContent;
56 import com.sun.syndication.feed.synd.SyndContentImpl;
57 import com.sun.syndication.feed.synd.SyndEntry;
58 import com.sun.syndication.feed.synd.SyndEntryImpl;
59 import com.sun.syndication.feed.synd.SyndFeed;
60 import com.sun.syndication.feed.synd.SyndFeedImpl;
61 import com.sun.syndication.io.SyndFeedOutput;
62
63
64
65
66
67
68 public class StreetSearchResultsDtoSerializer implements
69 IStreetSearchResultsDtoSerializer {
70
71 private static JAXBContext contextForList;
72
73
74
75
76 protected JsonConfig jsonConfig = new JsonConfig();
77
78
79
80
81 public StreetSearchResultsDtoSerializer() {
82 super();
83 try {
84 contextForList = JAXBContext.newInstance(StreetSearchResultsDto.class);
85 jsonConfig.setIgnoreTransientFields(true);
86
87 jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
88 public boolean apply(Object source, String name, Object value) {
89 if (name.contains("location")
90 || name.contains("gisFeature")) {
91 return true;
92 }
93 return false;
94 }
95 });
96 } catch (JAXBException e) {
97 throw new GeolocSearchException(e.getMessage(), e.getCause());
98 }
99 }
100
101
102
103 public void serialize(OutputStream outputStream, OutputFormat outputFormat,
104 StreetSearchResultsDto streetSearchResultsDto, boolean indent,int startPaginationIndex) {
105 if (!outputFormat.isSupported(GisgraphyServiceType.STREET)) {
106 throw new UnsupportedFormatException(outputFormat
107 + " is not applicable for street search");
108 }
109
110 else if (outputFormat == OutputFormat.JSON) {
111 serializeToJSON(outputStream,
112 streetSearchResultsDto,indent);
113 } else if (outputFormat==OutputFormat.ATOM){
114 serializeToFeed(outputStream,streetSearchResultsDto,OutputFormat.ATOM_VERSION, startPaginationIndex);
115 }
116 else if (outputFormat==OutputFormat.GEORSS) {
117 serializeToFeed(outputStream,streetSearchResultsDto,OutputFormat.RSS_VERSION, startPaginationIndex);
118 }
119 else {
120
121 serializeToXML(outputStream,
122 streetSearchResultsDto,indent);
123 }
124
125 return;
126 }
127
128 private void serializeToXML(OutputStream outputStream,
129 StreetSearchResultsDto streetSearchResultsDto,boolean indent) {
130 try {
131 Marshaller m = contextForList.createMarshaller();
132 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, indent);
133 m.marshal(streetSearchResultsDto, outputStream);
134 } catch (Exception e) {
135 throw new ServiceException(e);
136 }
137 }
138
139 private void serializeToJSON(OutputStream outputStream,
140 StreetSearchResultsDto streetSearchResultsDto,boolean indent){
141
142
143
144
145
146
147
148 JSON json = JSONSerializer.toJSON(streetSearchResultsDto, jsonConfig);
149 final Writer writer;
150 try {
151 writer = new OutputStreamWriter(outputStream, Constants.CHARSET);
152 } catch (Exception e) {
153 throw new GeolocSearchException("unknow encoding "
154 + Constants.CHARSET, e);
155 }
156
157 json.write(writer);
158 try {
159 writer.flush();
160 } catch (IOException e) {
161 throw new GeolocSearchException("error during flush", e);
162 }
163 }
164
165 @SuppressWarnings("unchecked")
166 private void serializeToFeed(OutputStream outputStream,
167 StreetSearchResultsDto streetSearchResultsDto,String feedVersion, int startPaginationIndex) {
168 SyndFeed synFeed = new SyndFeedImpl();
169 Writer oWriter = null;
170 try {
171
172 synFeed.setFeedType(feedVersion);
173
174
175 synFeed.setTitle(Constants.FEED_TITLE);
176 synFeed.setLink(Constants.FEED_LINK);
177 synFeed.setDescription(Constants.FEED_DESCRIPTION);
178 List<SyndEntry> entries = new ArrayList<SyndEntry>();
179
180 for (StreetDistance gisFeatureDistance : streetSearchResultsDto
181 .getResult()) {
182
183 SyndEntry entry = new SyndEntryImpl();
184 GeoRSSModule geoRSSModuleGML = new GMLModuleImpl();
185 OpenSearchModule openSearchModule = new OpenSearchModuleImpl();
186
187 geoRSSModuleGML.setLatitude(gisFeatureDistance.getLat());
188 geoRSSModuleGML.setLongitude(gisFeatureDistance.getLng());
189
190 openSearchModule
191 .setItemsPerPage(Pagination.DEFAULT_MAX_RESULTS);
192 openSearchModule
193 .setTotalResults(streetSearchResultsDto.getNumFound());
194 openSearchModule.setStartIndex(startPaginationIndex);
195
196 entry.getModules().add(openSearchModule);
197 entry.getModules().add(geoRSSModuleGML);
198 entry.setTitle(gisFeatureDistance.getName());
199 entry.setAuthor(Constants.MAIL_ADDRESS);
200 entry
201 .setLink(Constants.STREET_BASE_URL+
202 + gisFeatureDistance.getGid());
203 SyndContent description = new SyndContentImpl();
204 description.setType(OutputFormat.ATOM.getContentType());
205 description.setValue(gisFeatureDistance.getName());
206 entry.setDescription(description);
207 entries.add(entry);
208 }
209
210 synFeed.setEntries(entries);
211
212 try {
213 oWriter = new OutputStreamWriter(outputStream, Constants.CHARSET);
214 } catch (UnsupportedEncodingException e) {
215 throw new RuntimeException("unknow encoding "+Constants.CHARSET);
216 }
217
218
219 SyndFeedOutput output = new SyndFeedOutput();
220 try {
221 output.output(synFeed, oWriter);
222
223 oWriter.flush();
224 } catch (Exception e) {
225 throw new RuntimeException(e);
226 }
227
228
229 } finally {
230 if (oWriter != null)
231 try {
232 oWriter.close();
233 } catch (IOException e) {
234 throw new RuntimeException(e);
235 }
236 if (outputStream != null)
237 try {
238 outputStream.close();
239 } catch (IOException e) {
240 throw new RuntimeException(e);
241 }
242 }
243
244 }
245
246 }