Project

General

Profile

Download (9.08 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.ext.geo;
10

    
11
import java.io.ByteArrayInputStream;
12
import java.io.IOException;
13
import java.io.InputStream;
14
import java.io.StringWriter;
15
import java.net.URL;
16
import java.util.ArrayList;
17
import java.util.HashMap;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.TreeSet;
21

    
22
import javax.xml.stream.XMLOutputFactory;
23
import javax.xml.stream.XMLStreamException;
24
import javax.xml.stream.XMLStreamWriter;
25

    
26
import org.apache.log4j.Logger;
27
import org.jdom.Element;
28
import org.jdom.JDOMException;
29
import org.jdom.Namespace;
30

    
31
import eu.etaxonomy.cdm.common.CdmUtils;
32
import eu.etaxonomy.cdm.common.XmlHelp;
33

    
34
/**
35
 * Holds all values to map an NamedArea to a geo service area.
36
 *
37
 * TODO it must be possible to distinguish mappings for multiple layers in the same map service,
38
 *      that is the combination of GeoServiceType, URL and layer would be a unique key.
39
 *      This is however conflicting with the concept of the  subAreas which allows to combine multiple
40
 *      polygons from different layers.
41
 *      see also http://dev.e-taxonomy.eu/trac/ticket/4263
42
 *
43
 * @author a.mueller
44
 \* @since 11.08.2011
45
 *
46
 */
47
public class GeoServiceArea {
48
    @SuppressWarnings("unused")
49
    private static final Logger logger = Logger.getLogger(GeoServiceArea.class);
50

    
51
    private static final String VALUE = "value";
52
    private static final String FIELD = "field";
53
    private static final String LAYER = "layer";
54
    private static final String AREA = "area";
55
    private static final String MAP_SERVICE_NAMESPACE = "http://www.etaxonomy.eu/cdm";
56
    private static final String MAP_SERVICE = "mapService";
57

    
58

    
59
    public enum GeoServiceType{
60
        EDIT("Edit Geo Service"),
61
        WMS("WMS Service");
62

    
63
        private final String label;
64

    
65
        private GeoServiceType(String label){
66
            this.label = label;
67
        }
68

    
69
        public String getLabel(){
70
            return label;
71
        }
72
    }
73

    
74
    private final TreeSet<SubArea> subAreas = new TreeSet<SubArea>();
75
    private URL serviceUri;
76
    private GeoServiceType type;
77

    
78

    
79
    public class SubArea implements Comparable<SubArea>{
80
        private String layer;
81
        private String field;
82
        private String value;
83

    
84
        @Override
85
        public int hashCode() {
86
            int hash;
87
            hash = 236435;
88
            hash += layer != null ? layer.hashCode() * 29 : 32;
89
            hash += field != null ? field.hashCode() * 31 : 32;
90
            hash += value != null ? value.hashCode() * 37 : 32;
91
            return hash;
92
        }
93

    
94
        @Override
95
        public boolean equals(Object otherArea) {
96
            if (! (otherArea instanceof SubArea)){
97
                return false;
98
            }
99
            SubArea subArea = (SubArea)otherArea;
100
            if (CdmUtils.nullSafeEqual(layer, subArea.layer)
101
                    && CdmUtils.nullSafeEqual(field, subArea.field)
102
                    && CdmUtils.nullSafeEqual(value, subArea.value)
103
            ){
104
                return true;
105
            }else{
106
                return false;
107
            }
108
        }
109
        @Override
110
        public int compareTo(SubArea otherArea) {
111
            int compareLayer = CdmUtils.Nz(this.layer).compareToIgnoreCase(CdmUtils.Nz(otherArea.layer));
112
            int compareField = CdmUtils.Nz(this.field).compareToIgnoreCase(CdmUtils.Nz(otherArea.field));
113
            int compareValue = CdmUtils.Nz(this.value).compareToIgnoreCase(CdmUtils.Nz(otherArea.value));
114

    
115
            if (compareLayer != 0){
116
                return compareLayer;
117
            }else if (compareField != 0 ){
118
                return compareField;
119
            }else {
120
                return compareValue;
121
            }
122
        }
123

    
124

    
125
    }
126

    
127
    public void add(String layer, String field, String value){
128
        SubArea newArea = new SubArea();
129
        newArea.layer = layer;
130
        newArea.field = field;
131
        newArea.value = value;
132
        subAreas.add(newArea);
133
    }
134

    
135
    /**
136
     * Returns the areas as a layer, field, area nested map.
137
     * @return
138
     */
139
    public Map<String, Map<String, List<String>>> getAreasMap(){
140
        Map<String, Map<String, List<String>>> result = new HashMap<String, Map<String,List<String>>>();
141

    
142
        for (SubArea area : subAreas){
143
            //layer
144
            Map<String, List<String>> layer = result.get(area.layer);
145
            if (layer == null ){
146
                layer = new HashMap<String, List<String>>();
147
                result.put(area.layer, layer);
148
            }
149
            //field
150
            List<String> field = layer.get(area.field);
151
            if (field == null ){
152
                field = new ArrayList<String>();
153
                layer.put(area.field, field);
154
            }
155
            //value
156
            if (! field.contains(area.value)){
157
                field.add(area.value);
158
            }
159

    
160
        }
161
        return result;
162
    }
163

    
164
    public List<SubArea> getAreasList(){
165
        List<SubArea> result = new ArrayList<SubArea>();
166
        for (SubArea area : subAreas){
167
            result.add(area);
168
        }
169
        return result;
170
    }
171

    
172

    
173
    public static boolean isAreaMapping(String xml){
174
        //TODO check by parsing or only testing root + namespace
175
        GeoServiceArea mapping = valueOf(xml);
176
        if (mapping != null){
177
            return true;
178
        }else{
179
            return false;
180
        }
181
    }
182

    
183
    public static GeoServiceArea valueOf (String xml){
184
        if (xml == null){
185
            return null;
186
        }
187

    
188
//		StringReader reader = new StringReader (xml);
189
//		(new InputSource(reader));
190
//		InputStream is = new java.io.StringBufferInputStream(xml);
191
        InputStream is = new ByteArrayInputStream(xml.getBytes());
192
        GeoServiceArea result = new GeoServiceArea();
193

    
194
        try {
195
            Element root = XmlHelp.getRoot(is);
196
            if (! root.getName().equals(MAP_SERVICE) || ! root.getNamespace().getURI().equals(MAP_SERVICE_NAMESPACE)   ){
197
                return null;
198
            }else{
199
                //TODO schema validation
200

    
201
                Namespace ns = root.getNamespace();
202
                List<Element> elAreas = root.getChildren(AREA, ns);
203
                for (Element elArea : elAreas){
204
                    Element layer = elArea.getChild(LAYER, ns);
205
                    Element field = elArea.getChild(FIELD, ns);
206
                    //TODO multiple values
207
                    List<Element> values = elArea.getChildren(VALUE, ns);
208
                    for (Element value : values){
209
                        result.add(layer.getTextTrim(), field.getTextTrim(), value.getTextTrim());
210
                    }
211
                }
212
                return result;
213
            }
214

    
215

    
216
        } catch (JDOMException e) {
217
            throw new RuntimeException(e);
218
        } catch (IOException e) {
219
            throw new RuntimeException(e);
220
        }
221
    }
222

    
223
    /**
224
     * @return
225
     * @throws XMLStreamException
226
     */
227
    //TODO use JAXB or other marshalling techniques
228
    public String toXml() throws XMLStreamException{
229
        XMLStreamWriter writer = null;
230
            XMLOutputFactory factory = XMLOutputFactory.newInstance();
231
            StringWriter stringWriter = new StringWriter();
232
            writer = factory.createXMLStreamWriter(stringWriter);
233

    
234
            String rootNamespace = MAP_SERVICE_NAMESPACE;
235
            String rootName = MAP_SERVICE;
236

    
237

    
238
            // create header
239
            writer.writeStartDocument();
240
            writer.setDefaultNamespace(rootNamespace);
241

    
242
                // create root element
243
                writer.writeStartElement(rootName);
244

    
245
                writer.writeNamespace(null, rootNamespace);
246
                writer.writeAttribute("type", "editMapService");
247

    
248
                writeAreas(writer);
249

    
250
                writer.writeEndElement();
251
            writer.writeEndDocument();
252

    
253
            return stringWriter.getBuffer().toString();
254
    }
255

    
256
    private void writeAreas(XMLStreamWriter writer) throws XMLStreamException {
257
        Map<String, Map<String, List<String>>> areaMap = getAreasMap();
258
        //TODO multiple
259
        for (String layerKey : areaMap.keySet()){
260
            Map<String, List<String>> layer = areaMap.get(layerKey);
261
            for (String fieldKey: layer.keySet()){
262
                List<String> field = layer.get(fieldKey);
263
                //area
264
                writer.writeStartElement(AREA);
265
                //layer
266
                writer.writeStartElement(LAYER);
267
                writer.writeCharacters(layerKey);
268
                writer.writeEndElement();
269
                //field
270
                writer.writeStartElement(FIELD);
271
                writer.writeCharacters(fieldKey);
272
                writer.writeEndElement();
273
                //value
274
                for (String value : field){
275
                    writer.writeStartElement(VALUE);
276
                    writer.writeCharacters(value);
277
                    writer.writeEndElement();
278
                }
279
                writer.writeEndElement();
280
            }
281
        }
282

    
283
    }
284

    
285

    
286
    public int size() {
287
        return this.subAreas.size();
288
    }
289

    
290
}
(8-8/14)