3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.ext
.geo
;
12 import java
.io
.ByteArrayInputStream
;
13 import java
.io
.IOException
;
14 import java
.io
.InputStream
;
15 import java
.io
.StringWriter
;
17 import java
.util
.ArrayList
;
18 import java
.util
.HashMap
;
19 import java
.util
.List
;
21 import java
.util
.TreeSet
;
23 import javax
.xml
.stream
.XMLOutputFactory
;
24 import javax
.xml
.stream
.XMLStreamException
;
25 import javax
.xml
.stream
.XMLStreamWriter
;
27 import org
.apache
.log4j
.Logger
;
28 import org
.jdom
.Element
;
29 import org
.jdom
.JDOMException
;
30 import org
.jdom
.Namespace
;
32 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
33 import eu
.etaxonomy
.cdm
.common
.XmlHelp
;
36 * Holds all values to map an NamedArea to a geo service area
41 public class GeoServiceArea
{
42 @SuppressWarnings("unused")
43 private static final Logger logger
= Logger
.getLogger(GeoServiceArea
.class);
45 private static final String VALUE
= "value";
46 private static final String FIELD
= "field";
47 private static final String LAYER
= "layer";
48 private static final String AREA
= "area";
49 private static final String MAP_SERVICE_NAMESPACE
= "http://www.etaxonomy.eu/cdm";
50 private static final String MAP_SERVICE
= "mapService";
53 public enum GeoServiceType
{
54 EDIT("Edit Geo Service"),
59 private GeoServiceType(String label
){
63 public String
getLabel(){
68 private TreeSet
<SubArea
> subAreas
= new TreeSet
<SubArea
>();
69 private URL serviceUri
;
70 private GeoServiceType type
;
73 public class SubArea
implements Comparable
<SubArea
>{
79 * @see java.lang.Object#hashCode()
82 public int hashCode() {
85 hash
+= layer
!= null ? layer
.hashCode() * 29 : 32;
86 hash
+= field
!= null ? field
.hashCode() * 31 : 32;
87 hash
+= value
!= null ? value
.hashCode() * 37 : 32;
91 * @see java.lang.Object#equals(java.lang.Object)
94 public boolean equals(Object otherArea
) {
95 if (! (otherArea
instanceof SubArea
)){
98 SubArea subArea
= (SubArea
)otherArea
;
99 if (CdmUtils
.nullSafeEqual(layer
, subArea
.layer
)
100 && CdmUtils
.nullSafeEqual(field
, subArea
.field
)
101 && CdmUtils
.nullSafeEqual(value
, subArea
.value
)
109 public int compareTo(SubArea otherArea
) {
110 int compareLayer
= CdmUtils
.Nz(this.layer
).compareToIgnoreCase(CdmUtils
.Nz(otherArea
.layer
));
111 int compareField
= CdmUtils
.Nz(this.field
).compareToIgnoreCase(CdmUtils
.Nz(otherArea
.field
));
112 int compareValue
= CdmUtils
.Nz(this.value
).compareToIgnoreCase(CdmUtils
.Nz(otherArea
.value
));
114 if (compareLayer
!= 0){
116 }else if (compareField
!= 0 ){
126 public void add(String layer
, String field
, String value
){
127 SubArea newArea
= new SubArea();
128 newArea
.layer
= layer
;
129 newArea
.field
= field
;
130 newArea
.value
= value
;
131 subAreas
.add(newArea
);
135 * Returns the areas as a layer, field, area nested map.
138 public Map
<String
, Map
<String
, List
<String
>>> getAreasMap(){
139 Map
<String
, Map
<String
, List
<String
>>> result
= new HashMap
<String
, Map
<String
,List
<String
>>>();
141 for (SubArea area
: subAreas
){
143 Map
<String
, List
<String
>> layer
= result
.get(area
.layer
);
145 layer
= new HashMap
<String
, List
<String
>>();
146 result
.put(area
.layer
, layer
);
149 List
<String
> field
= layer
.get(area
.field
);
151 field
= new ArrayList
<String
>();
152 layer
.put(area
.field
, field
);
155 if (! field
.contains(area
.value
)){
156 field
.add(area
.value
);
163 public List
<SubArea
> getAreasList(){
164 List
<SubArea
> result
= new ArrayList
<SubArea
>();
165 for (SubArea area
: subAreas
){
172 public static boolean isAreaMapping(String xml
){
173 //TODO check by parsing or only testing root + namespace
174 GeoServiceArea mapping
= valueOf(xml
);
175 if (mapping
!= null){
182 public static GeoServiceArea
valueOf (String xml
){
187 // StringReader reader = new StringReader (xml);
188 // (new InputSource(reader));
189 // InputStream is = new java.io.StringBufferInputStream(xml);
190 InputStream is
= new ByteArrayInputStream(xml
.getBytes());
191 GeoServiceArea result
= new GeoServiceArea();
194 Element root
= XmlHelp
.getRoot(is
);
195 if (! root
.getName().equals(MAP_SERVICE
) || ! root
.getNamespace().getURI().equals(MAP_SERVICE_NAMESPACE
) ){
198 //TODO schema validation
200 Namespace ns
= root
.getNamespace();
201 List
<Element
> elAreas
= root
.getChildren(AREA
, ns
);
202 for (Element elArea
: elAreas
){
203 Element layer
= elArea
.getChild(LAYER
, ns
);
204 Element field
= elArea
.getChild(FIELD
, ns
);
205 //TODO multiple values
206 List
<Element
> values
= elArea
.getChildren(VALUE
, ns
);
207 for (Element value
: values
){
208 result
.add(layer
.getTextTrim(), field
.getTextTrim(), value
.getTextTrim());
215 } catch (JDOMException e
) {
216 throw new RuntimeException(e
);
217 } catch (IOException e
) {
218 throw new RuntimeException(e
);
224 * @throws XMLStreamException
226 //TODO use JAXB or other marshalling techniques
227 public String
toXml() throws XMLStreamException
{
228 XMLStreamWriter writer
= null;
229 XMLOutputFactory factory
= XMLOutputFactory
.newInstance();
230 StringWriter stringWriter
= new StringWriter();
231 writer
= factory
.createXMLStreamWriter(stringWriter
);
233 String rootNamespace
= MAP_SERVICE_NAMESPACE
;
234 String rootName
= MAP_SERVICE
;
238 writer
.writeStartDocument();
239 writer
.setDefaultNamespace(rootNamespace
);
241 // create root element
242 writer
.writeStartElement(rootName
);
244 writer
.writeNamespace(null, rootNamespace
);
245 writer
.writeAttribute("type", "editMapService");
249 writer
.writeEndElement();
250 writer
.writeEndDocument();
252 return stringWriter
.getBuffer().toString();
255 private void writeAreas(XMLStreamWriter writer
) throws XMLStreamException
{
256 Map
<String
, Map
<String
, List
<String
>>> areaMap
= getAreasMap();
258 for (String layerKey
: areaMap
.keySet()){
259 Map
<String
, List
<String
>> layer
= areaMap
.get(layerKey
);
260 for (String fieldKey
: layer
.keySet()){
261 List
<String
> field
= layer
.get(fieldKey
);
263 writer
.writeStartElement(AREA
);
265 writer
.writeStartElement(LAYER
);
266 writer
.writeCharacters(layerKey
);
267 writer
.writeEndElement();
269 writer
.writeStartElement(FIELD
);
270 writer
.writeCharacters(fieldKey
);
271 writer
.writeEndElement();
273 for (String value
: field
){
274 writer
.writeStartElement(VALUE
);
275 writer
.writeCharacters(value
);
276 writer
.writeEndElement();
278 writer
.writeEndElement();
286 return this.subAreas
.size();