Project

General

Profile

« Previous | Next » 

Revision 363387d2

Added by Andreas Müller about 8 years ago

Implement natural ordering for distributions in data portal #5677

View differences:

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.StringWriter;
16
import java.net.URL;
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.apache.log4j.Logger;
28
import org.jdom.Element;
29
import org.jdom.JDOMException;
30
import org.jdom.Namespace;
31

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

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

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

  
59

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

  
64
        private final String label;
65

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

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

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

  
79

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

  
85
        /* (non-Javadoc)
86
         * @see java.lang.Object#hashCode()
87
         */
88
        @Override
89
        public int hashCode() {
90
            int hash;
91
            hash = 236435;
92
            hash += layer != null ? layer.hashCode() * 29 : 32;
93
            hash += field != null ? field.hashCode() * 31 : 32;
94
            hash += value != null ? value.hashCode() * 37 : 32;
95
            return hash;
96
        }
97
        /* (non-Javadoc)
98
         * @see java.lang.Object#equals(java.lang.Object)
99
         */
100
        @Override
101
        public boolean equals(Object otherArea) {
102
            if (! (otherArea instanceof SubArea)){
103
                return false;
104
            }
105
            SubArea subArea = (SubArea)otherArea;
106
            if (CdmUtils.nullSafeEqual(layer, subArea.layer)
107
                    && CdmUtils.nullSafeEqual(field, subArea.field)
108
                    && CdmUtils.nullSafeEqual(value, subArea.value)
109
            ){
110
                return true;
111
            }else{
112
                return false;
113
            }
114
        }
115
        @Override
116
        public int compareTo(SubArea otherArea) {
117
            int compareLayer = CdmUtils.Nz(this.layer).compareToIgnoreCase(CdmUtils.Nz(otherArea.layer));
118
            int compareField = CdmUtils.Nz(this.field).compareToIgnoreCase(CdmUtils.Nz(otherArea.field));
119
            int compareValue = CdmUtils.Nz(this.value).compareToIgnoreCase(CdmUtils.Nz(otherArea.value));
120

  
121
            if (compareLayer != 0){
122
                return compareLayer;
123
            }else if (compareField != 0 ){
124
                return compareField;
125
            }else {
126
                return compareValue;
127
            }
128
        }
129

  
130

  
131
    }
132

  
133
    public void add(String layer, String field, String value){
134
        SubArea newArea = new SubArea();
135
        newArea.layer = layer;
136
        newArea.field = field;
137
        newArea.value = value;
138
        subAreas.add(newArea);
139
    }
140

  
141
    /**
142
     * Returns the areas as a layer, field, area nested map.
143
     * @return
144
     */
145
    public Map<String, Map<String, List<String>>> getAreasMap(){
146
        Map<String, Map<String, List<String>>> result = new HashMap<String, Map<String,List<String>>>();
147

  
148
        for (SubArea area : subAreas){
149
            //layer
150
            Map<String, List<String>> layer = result.get(area.layer);
151
            if (layer == null ){
152
                layer = new HashMap<String, List<String>>();
153
                result.put(area.layer, layer);
154
            }
155
            //field
156
            List<String> field = layer.get(area.field);
157
            if (field == null ){
158
                field = new ArrayList<String>();
159
                layer.put(area.field, field);
160
            }
161
            //value
162
            if (! field.contains(area.value)){
163
                field.add(area.value);
164
            }
165

  
166
        }
167
        return result;
168
    }
169

  
170
    public List<SubArea> getAreasList(){
171
        List<SubArea> result = new ArrayList<SubArea>();
172
        for (SubArea area : subAreas){
173
            result.add(area);
174
        }
175
        return result;
176
    }
177

  
178

  
179
    public static boolean isAreaMapping(String xml){
180
        //TODO check by parsing or only testing root + namespace
181
        GeoServiceArea mapping = valueOf(xml);
182
        if (mapping != null){
183
            return true;
184
        }else{
185
            return false;
186
        }
187
    }
188

  
189
    public static GeoServiceArea valueOf (String xml){
190
        if (xml == null){
191
            return null;
192
        }
193

  
194
//		StringReader reader = new StringReader (xml);
195
//		(new InputSource(reader));
196
//		InputStream is = new java.io.StringBufferInputStream(xml);
197
        InputStream is = new ByteArrayInputStream(xml.getBytes());
198
        GeoServiceArea result = new GeoServiceArea();
199

  
200
        try {
201
            Element root = XmlHelp.getRoot(is);
202
            if (! root.getName().equals(MAP_SERVICE) || ! root.getNamespace().getURI().equals(MAP_SERVICE_NAMESPACE)   ){
203
                return null;
204
            }else{
205
                //TODO schema validation
206

  
207
                Namespace ns = root.getNamespace();
208
                List<Element> elAreas = root.getChildren(AREA, ns);
209
                for (Element elArea : elAreas){
210
                    Element layer = elArea.getChild(LAYER, ns);
211
                    Element field = elArea.getChild(FIELD, ns);
212
                    //TODO multiple values
213
                    List<Element> values = elArea.getChildren(VALUE, ns);
214
                    for (Element value : values){
215
                        result.add(layer.getTextTrim(), field.getTextTrim(), value.getTextTrim());
216
                    }
217
                }
218
                return result;
219
            }
220

  
221

  
222
        } catch (JDOMException e) {
223
            throw new RuntimeException(e);
224
        } catch (IOException e) {
225
            throw new RuntimeException(e);
226
        }
227
    }
228

  
229
    /**
230
     * @return
231
     * @throws XMLStreamException
232
     */
233
    //TODO use JAXB or other marshalling techniques
234
    public String toXml() throws XMLStreamException{
235
        XMLStreamWriter writer = null;
236
            XMLOutputFactory factory = XMLOutputFactory.newInstance();
237
            StringWriter stringWriter = new StringWriter();
238
            writer = factory.createXMLStreamWriter(stringWriter);
239

  
240
            String rootNamespace = MAP_SERVICE_NAMESPACE;
241
            String rootName = MAP_SERVICE;
242

  
243

  
244
            // create header
245
            writer.writeStartDocument();
246
            writer.setDefaultNamespace(rootNamespace);
247

  
248
                // create root element
249
                writer.writeStartElement(rootName);
250

  
251
                writer.writeNamespace(null, rootNamespace);
252
                writer.writeAttribute("type", "editMapService");
253

  
254
                writeAreas(writer);
255

  
256
                writer.writeEndElement();
257
            writer.writeEndDocument();
258

  
259
            return stringWriter.getBuffer().toString();
260
    }
261

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

  
289
    }
290

  
291

  
292
    public int size() {
293
        return this.subAreas.size();
294
    }
295

  
296
}
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.StringWriter;
16
import java.net.URL;
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.apache.log4j.Logger;
28
import org.jdom.Element;
29
import org.jdom.JDOMException;
30
import org.jdom.Namespace;
31

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

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

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

  
59

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

  
64
        private final String label;
65

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

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

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

  
79

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

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

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

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

  
125

  
126
    }
127

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

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

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

  
161
        }
162
        return result;
163
    }
164

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

  
173

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

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

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

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

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

  
216

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

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

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

  
238

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

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

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

  
249
                writeAreas(writer);
250

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

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

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

  
284
    }
285

  
286

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

  
291
}

Also available in: Unified diff