preliminary implementation for generic geoMapService mapping (supports no multiple...
[cdmlib.git] / cdmlib-ext / src / main / java / eu / etaxonomy / cdm / ext / geo / GeoServiceArea.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.ext.geo;
11
12 import java.io.ByteArrayInputStream;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.StringReader;
16 import java.io.StringWriter;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.TreeSet;
22
23 import javax.xml.stream.XMLOutputFactory;
24 import javax.xml.stream.XMLStreamException;
25 import javax.xml.stream.XMLStreamWriter;
26
27 import org.jdom.Element;
28 import org.jdom.JDOMException;
29 import org.jdom.Namespace;
30 import org.xml.sax.InputSource;
31
32 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
33 import eu.etaxonomy.cdm.common.CdmUtils;
34 import eu.etaxonomy.cdm.common.XmlHelp;
35 import eu.etaxonomy.cdm.model.common.Annotation;
36 import eu.etaxonomy.cdm.model.common.AnnotationType;
37 import eu.etaxonomy.cdm.model.common.Language;
38 import eu.etaxonomy.cdm.model.location.NamedArea;
39
40 /**
41 * Holds all values to map an NamedArea to a geo service area
42 * @author a.mueller
43 * @date 11.08.2011
44 *
45 */
46 public class GeoServiceArea {
47
48 private static final String VALUE = "value";
49 private static final String FIELD = "field";
50 private static final String LAYER = "layer";
51 private static final String AREA = "area";
52 private static final String MAP_SERVICE_NAMESPACE = "http://www.etaxonomy.eu/cdm";
53 private static final String MAP_SERVICE = "mapService";
54 TreeSet<SubArea> subAreas = new TreeSet<SubArea>();
55
56 private class SubArea implements Comparable<SubArea>{
57 private String layer;
58 private String field;
59 private String value;
60 /* (non-Javadoc)
61 * @see java.lang.Object#hashCode()
62 */
63 @Override
64 public int hashCode() {
65 int hash;
66 hash = 236435;
67 hash += layer != null ? layer.hashCode() * 29 : 32;
68 hash += field != null ? field.hashCode() * 31 : 32;
69 hash += value != null ? value.hashCode() * 37 : 32;
70 return hash;
71 }
72 /* (non-Javadoc)
73 * @see java.lang.Object#equals(java.lang.Object)
74 */
75 @Override
76 public boolean equals(Object otherArea) {
77 if (! (otherArea instanceof SubArea)){
78 return false;
79 }
80 SubArea subArea = (SubArea)otherArea;
81 if (CdmUtils.nullSafeEqual(layer, subArea.layer)
82 && CdmUtils.nullSafeEqual(field, subArea.field)
83 && CdmUtils.nullSafeEqual(value, subArea.value)){
84 return true;
85 }else{
86 return false;
87 }
88 }
89 @Override
90 public int compareTo(SubArea otherArea) {
91 int compareLayer = CdmUtils.Nz(this.layer).compareToIgnoreCase(CdmUtils.Nz(otherArea.layer));
92 int compareField = CdmUtils.Nz(this.field).compareToIgnoreCase(CdmUtils.Nz(otherArea.field));
93 int compareValue = CdmUtils.Nz(this.value).compareToIgnoreCase(CdmUtils.Nz(otherArea.value));
94
95 if (compareLayer != 0){
96 return compareLayer;
97 }else if (compareField != 0 ){
98 return compareField;
99 }else {
100 return compareValue;
101 }
102 }
103
104
105 }
106
107 public void add(String layer, String field, String value){
108 SubArea newArea = new SubArea();
109 newArea.layer = layer;
110 newArea.field = field;
111 newArea.value = value;
112 subAreas.add(newArea);
113 }
114
115 public Map<String, Map<String, List<String>>> getAreas(){
116 Map<String, Map<String, List<String>>> result = new HashMap<String, Map<String,List<String>>>();
117
118 for (SubArea area : subAreas){
119 //layer
120 Map<String, List<String>> layer = result.get(area.layer);
121 if (layer == null ){
122 layer = new HashMap<String, List<String>>();
123 result.put(area.layer, layer);
124 }
125 //field
126 List<String> field = layer.get(area.field);
127 if (field == null ){
128 field = new ArrayList<String>();
129 layer.put(area.field, field);
130 }
131 //value
132 if (! field.contains(area.value)){
133 field.add(area.value);
134 }
135
136 }
137 return result;
138 }
139
140 public static GeoServiceArea valueOf (String xml){
141 // StringReader reader = new StringReader (xml);
142 // (new InputSource(reader));
143 // InputStream is = new java.io.StringBufferInputStream(xml);
144 InputStream is = new ByteArrayInputStream(xml.getBytes());
145 GeoServiceArea result = new GeoServiceArea();
146
147 try {
148 Element root = XmlHelp.getRoot(is);
149 if (! root.getName().equals(MAP_SERVICE) || ! root.getNamespace().getURI().equals(MAP_SERVICE_NAMESPACE) ){
150 return null;
151 }else{
152 //TODO schema validation
153
154 Namespace ns = root.getNamespace();
155 List<Element> elAreas = root.getChildren(AREA, ns);
156 for (Element elArea : elAreas){
157 Element layer = elArea.getChild(LAYER, ns);
158 Element field = elArea.getChild(FIELD, ns);
159 //TODO multiple values
160 List<Element> values = elArea.getChildren(VALUE, ns);
161 for (Element value : values){
162 result.add(layer.getTextTrim(), field.getTextTrim(), value.getTextTrim());
163 }
164 }
165 return result;
166 }
167
168
169
170 } catch (JDOMException e) {
171 throw new RuntimeException(e);
172 } catch (IOException e) {
173 throw new RuntimeException(e);
174 }
175 }
176
177 public String toXml() throws XMLStreamException{
178 XMLStreamWriter writer = null;
179 XMLOutputFactory factory = XMLOutputFactory.newInstance();
180 StringWriter stringWriter = new StringWriter();
181 writer = factory.createXMLStreamWriter(stringWriter);
182
183 String rootNamespace = MAP_SERVICE_NAMESPACE;
184 String rootName = MAP_SERVICE;
185
186
187 // create header
188 writer.writeStartDocument();
189 writer.setDefaultNamespace(rootNamespace);
190
191 // create root element
192 writer.writeStartElement(rootName);
193
194 writer.writeNamespace(null, rootNamespace);
195 writer.writeAttribute("type", "editMapService");
196
197 writeAreas(writer);
198
199 writer.writeEndElement();
200 writer.writeEndDocument();
201
202 return stringWriter.getBuffer().toString();
203 }
204
205 private void writeAreas(XMLStreamWriter writer) throws XMLStreamException {
206 Map<String, Map<String, List<String>>> areaMap = getAreas();
207 //TODO multiple
208 for (String layerKey : areaMap.keySet()){
209 Map<String, List<String>> layer = areaMap.get(layerKey);
210 for (String fieldKey: layer.keySet()){
211 List<String> field = layer.get(fieldKey);
212 //area
213 writer.writeStartElement(AREA);
214 //layer
215 writer.writeStartElement(LAYER);
216 writer.writeCharacters(layerKey);
217 writer.writeEndElement();
218 //field
219 writer.writeStartElement(FIELD);
220 writer.writeCharacters(fieldKey);
221 writer.writeEndElement();
222 //value
223 for (String value : field){
224 writer.writeStartElement(VALUE);
225 writer.writeCharacters(value);
226 writer.writeEndElement();
227 }
228 writer.writeEndElement();
229 }
230 }
231
232 }
233
234 /**
235 * Transforms the area to an geoservice area
236 * @param area the NamedArea
237 * @param appConfig for future use
238 * @return
239 */
240 public static GeoServiceArea valueOf(NamedArea area, ICdmApplicationConfiguration appConfig) {
241 for (Annotation annotation : area.getAnnotations()){
242 if (AnnotationType.TECHNICAL().equals(annotation.getAnnotationType())){
243 GeoServiceArea areas = valueOf(annotation.getText());
244 return areas;
245 }
246 }
247
248 return null;
249 }
250
251 public static void set(NamedArea areaBangka, GeoServiceArea geoServiceArea) throws XMLStreamException {
252 AnnotationType type = AnnotationType.TECHNICAL();
253 Annotation annotation = Annotation.NewInstance(geoServiceArea.toXml(), type, Language.DEFAULT());
254 areaBangka.addAnnotation(annotation);
255 }
256
257 public int size() {
258 return this.subAreas.size();
259 }
260
261 }