Project

General

Profile

Download (8.96 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
 *      <BR><BR>
42
 *      see also https://dev.e-taxonomy.eu/redmine/issues/4263
43
 *
44
 * @author a.mueller
45
 * @since 11.08.2011
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<>();
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
    public void add(String layer, String field, String value){
126
        SubArea newArea = new SubArea();
127
        newArea.layer = layer;
128
        newArea.field = field;
129
        newArea.value = value;
130
        subAreas.add(newArea);
131
    }
132

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

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

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

    
169

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

    
180
    public static GeoServiceArea valueOf (String xml){
181
        if (xml == null){
182
            return null;
183
        }
184

    
185
//		StringReader reader = new StringReader (xml);
186
//		(new InputSource(reader));
187
//		InputStream is = new java.io.StringBufferInputStream(xml);
188
        InputStream is = new ByteArrayInputStream(xml.getBytes());
189
        GeoServiceArea result = new GeoServiceArea();
190

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

    
198
                Namespace ns = root.getNamespace();
199
                List<Element> elAreas = root.getChildren(AREA, ns);
200
                for (Element elArea : elAreas){
201
                    Element layer = elArea.getChild(LAYER, ns);
202
                    Element field = elArea.getChild(FIELD, ns);
203
                    //TODO multiple values
204
                    List<Element> values = elArea.getChildren(VALUE, ns);
205
                    for (Element value : values){
206
                        result.add(layer.getTextTrim(), field.getTextTrim(), value.getTextTrim());
207
                    }
208
                }
209
                return result;
210
            }
211
        } catch (JDOMException e) {
212
            throw new RuntimeException(e);
213
        } catch (IOException e) {
214
            throw new RuntimeException(e);
215
        }
216
    }
217

    
218
    //TODO use JAXB or other marshalling techniques
219
    public String toXml() throws XMLStreamException{
220
        XMLStreamWriter writer = null;
221
            XMLOutputFactory factory = XMLOutputFactory.newInstance();
222
            StringWriter stringWriter = new StringWriter();
223
            writer = factory.createXMLStreamWriter(stringWriter);
224

    
225
            String rootNamespace = MAP_SERVICE_NAMESPACE;
226
            String rootName = MAP_SERVICE;
227

    
228
            // create header
229
            writer.writeStartDocument();
230
            writer.setDefaultNamespace(rootNamespace);
231

    
232
                // create root element
233
                writer.writeStartElement(rootName);
234

    
235
                writer.writeNamespace(null, rootNamespace);
236
                writer.writeAttribute("type", "editMapService");
237

    
238
                writeAreas(writer);
239

    
240
                writer.writeEndElement();
241
            writer.writeEndDocument();
242

    
243
            return stringWriter.getBuffer().toString();
244
    }
245

    
246
    private void writeAreas(XMLStreamWriter writer) throws XMLStreamException {
247
        Map<String, Map<String, List<String>>> areaMap = getAreasMap();
248
        //TODO multiple
249
        for (String layerKey : areaMap.keySet()){
250
            Map<String, List<String>> layer = areaMap.get(layerKey);
251
            for (String fieldKey: layer.keySet()){
252
                List<String> field = layer.get(fieldKey);
253
                //area
254
                writer.writeStartElement(AREA);
255
                //layer
256
                writer.writeStartElement(LAYER);
257
                writer.writeCharacters(layerKey);
258
                writer.writeEndElement();
259
                //field
260
                writer.writeStartElement(FIELD);
261
                writer.writeCharacters(fieldKey);
262
                writer.writeEndElement();
263
                //value
264
                for (String value : field){
265
                    writer.writeStartElement(VALUE);
266
                    writer.writeCharacters(value);
267
                    writer.writeEndElement();
268
                }
269
                writer.writeEndElement();
270
            }
271
        }
272
    }
273

    
274
    public int size() {
275
        return this.subAreas.size();
276
    }
277
}
(6-6/11)