Statistics
| Revision:

gvsig-raster / org.gvsig.raster.wms / trunk / org.gvsig.raster.wms / org.gvsig.raster.wms.app.wmsclient / src / main / java / org / gvsig / raster / wms / app / wmsclient / wmc / WebMapContext.java @ 2484

History | View | Annotate | Download (35.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
 
23
package org.gvsig.raster.wms.app.wmsclient.wmc;
24

    
25
import java.awt.Dimension;
26
import java.awt.geom.Rectangle2D;
27
import java.io.BufferedReader;
28
import java.io.File;
29
import java.io.FileInputStream;
30
import java.io.FileNotFoundException;
31
import java.io.FileReader;
32
import java.io.IOException;
33
import java.util.ArrayList;
34
import java.util.Arrays;
35
import java.util.HashMap;
36
import java.util.HashSet;
37
import java.util.Hashtable;
38
import java.util.List;
39
import java.util.Vector;
40

    
41
import org.cresques.cts.ICoordTrans;
42
import org.cresques.cts.IProjection;
43
import org.gvsig.app.ApplicationLocator;
44
import org.gvsig.app.project.documents.view.DefaultViewDocument;
45
import org.gvsig.fmap.crs.CRSFactory;
46
import org.gvsig.fmap.dal.coverage.exception.ImportMapContextException;
47
import org.gvsig.fmap.mapcontext.exceptions.UnsupportedVersionLayerException;
48
import org.gvsig.fmap.mapcontext.layers.FLayer;
49
import org.gvsig.fmap.mapcontext.layers.FLayers;
50
import org.gvsig.i18n.Messages;
51
import org.gvsig.raster.wms.app.wmsclient.layer.FLyrWMS;
52
import org.gvsig.raster.wms.io.RemoteWMSStyle;
53
import org.gvsig.raster.wms.io.WMSDataParameters;
54
import org.gvsig.raster.wms.io.WMSDataParametersImpl;
55
import org.kxml2.io.KXmlParser;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58
import org.xmlpull.v1.XmlPullParserException;
59

    
60

    
61
/**
62
 * Class that loads and produces WebMapContext files and holds its attributes.
63
 *
64
 * You can create a blank WebMapContext instance using the default constructor
65
 * or an already initialized instance by specifying a source file. In the last
66
 * case the file will be readed and the values loaded an holded by the instance.
67
 *
68
 * You can get the equivalent WebMapContext XML document by calling the method
69
 * getXML() supplying the ProjectView that you want to export and depending on
70
 * the value of the fileVersion field (currently you can use "1.1.0" (default),
71
 * "1.0.0" or "0.4.1" to specify the destination document version.
72
 *
73
 * @author jaume dominguez faus - jaume.dominguez@iver.es
74
 */
75
public class WebMapContext {
76
        public final static String FILE_EXTENSION = ".cml";
77
        private Logger  log = LoggerFactory.getLogger(WebMapContext.class); 
78
        static final ArrayList<String> supportedVersions = new ArrayList<String>();
79
        static public final ArrayList<String> exportVersions    = new ArrayList<String>();
80
        static private HashSet supportedLayers = new HashSet();
81
        private File mapContextFile;
82
        private String encoding = "UTF-8";
83
        private String WMC_START_TAG;
84

    
85
        // MapContext stuff
86
        public String fileVersion = null;
87
        public Dimension windowSize = null;
88
        public String srs = null;
89
        public Rectangle2D bBox = null;
90
        public String title = null;
91
        public String id = null;
92
        public String xmlns = null;
93
        public String xmlns_xlink = null;
94
        public String xmlns_xsi = null;;
95
        public String xsi_schemaLocation = null;
96
        public String _abstract = null;
97
        public List<String> keywordList = null;
98
        public Dimension logoURLSize = null;
99
        public String logoURLFormat = null;
100
        public String logoURL = null;
101
        public String descriptionURLFormat = null;
102
        public String descriptionURL = null;
103
        public boolean contactInfo = false;
104
        public String contactPerson = null;
105
        public String contactOrganization = null;
106
        public String contactPosition = null;
107
        public String address = null;
108
        public String city = null;
109
        public String stateOrProvince = null;
110
        public String postCode = null;
111
        public String country = null;
112
        public String telephone = null;
113
        public String fax = null;
114
        public String email = null;
115

    
116
        private StringBuffer errorMessages;
117

    
118
        List<FLyrWMS>            layerList  = null;
119
        List<WMSDataParameters>  paramsList = null;
120

    
121
        Hashtable<Object, String[]>  srsList = null;
122
        
123
        /**
124
         * key: server URL (URL)
125
         * value: server title (String)
126
         */
127
        Hashtable<String, String> serverTitles = null;
128

    
129
        /**
130
         * key: layer FLyrWMS
131
         * value: layer abstract (String)
132
         */
133
        Hashtable layerAbstracts = null;
134

    
135
        /**
136
         * key: layer FLyrWMS
137
         * value: layer formats (String[])
138
         */
139
        Hashtable layerFormats = null;
140

    
141
        /**
142
         * key: layer FLyrWMS
143
         * value: styles (FMapWMSStyle[])
144
         */
145
        Hashtable layerStyles = null;
146

    
147

    
148
        static {
149
                supportedVersions.add("1.1.0");
150
                supportedVersions.add("1.0.0");
151
                supportedVersions.add("0.1.4");
152
        }
153

    
154
        static {
155
                exportVersions.add("1.1.0");
156
                exportVersions.add("1.0.0");
157
                exportVersions.add("0.1.4");
158
        }
159

    
160
        static {
161
                supportedLayers.add(FLyrWMS.class);
162
        }
163

    
164

    
165
        /**
166
         * Initializes the WebMapContext properties from the values in the WebMapContext (.cml)
167
         * file passed in the argument.
168
         * @param file
169
         * @throws UnsupportedVersionLayerException
170
         * @throws ImportMapContextException
171
         */
172
        public void readFile(File file) throws UnsupportedVersionLayerException, ImportMapContextException {
173
                this.mapContextFile = file;
174
                errorMessages = new StringBuffer();
175
                if (getVersion() != null) {
176
                        if (supportedVersions.contains(getVersion())) {
177
                                WMC_START_TAG = WebMapContextTags.VIEW_CONTEXT;
178
                                if (getVersion().equals("0.1.4")) {
179
                                        WMC_START_TAG = WebMapContextTags.VIEW_CONTEXT_0_1_4;
180
                                        parse1_1_0(file);
181
                                } else if (getVersion().equals("1.1.0")) {
182
                                        parse1_1_0(file);
183
                                } else if (getVersion().equals("1.0.0")) {
184
                                        parse1_1_0(file);
185
                                } else {
186
                                        parseDefaultVersion(file);
187
                                }
188

    
189
                                // Once parsed, check errors
190
                                if (errorMessages.length() > 0) {
191
                                        throw new ImportMapContextException(errorMessages.toString(), false);
192
                                }
193
                        } else {
194
                                throw new UnsupportedVersionLayerException(file.getName(), null);
195
                        }
196
                }
197
        }
198

    
199

    
200
        /**
201
         * If no version was recognized then will parse the default one which is supposed
202
         * to be the best available.
203
         * @param file
204
         * @throws ImportMapContextException
205
         */
206
        private void parseDefaultVersion(File file) throws ImportMapContextException {
207
                parse1_1_0(file);
208
        }
209

    
210
        /**
211
         * Reads the header of the Weg Map Context file and determines which version
212
         * it belongs to.
213
         * @return String.
214
         */
215
        private String getVersion() {
216
                if (fileVersion == null) {
217
                        String v = null;
218
                        try {
219
                                FileReader fr = new FileReader(mapContextFile);
220
                                KXmlParser parser = new KXmlParser();
221
                                parser.setInput(fr);
222
                                parser.nextTag();
223
                            if ( parser.getEventType() != KXmlParser.END_DOCUMENT )        {
224
                                    if ((parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT) == 0) ||
225
                                             parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT_0_1_4) == 0) {
226
                                            v = parser.getAttributeValue("", WebMapContextTags.VERSION);
227
                                    }
228
                            }
229
                        } catch (FileNotFoundException fnfEx) {
230
                        } catch (XmlPullParserException xmlEx) {
231
                                xmlEx.printStackTrace();
232
                        } catch (IOException e) {
233
                        }
234
                        fileVersion = v;
235
                }
236
                return fileVersion;
237
        }
238
        
239
        private void readEnconding(File file) {
240
                FileReader fr = null;
241
                try {
242
                        fr = new FileReader(file);
243
                    BufferedReader br = new BufferedReader(fr);
244
                    char[] buffer = new char[100];
245
                    br.read(buffer);
246
                    StringBuffer st = new StringBuffer(new String(buffer));
247
                    String searchText = "encoding=\"";
248
                    int index = st.indexOf(searchText);
249
                    if (index>-1) {
250
                            st.delete(0, index+searchText.length());
251
                            encoding = st.substring(0, st.indexOf("\""));
252
                    }
253
                    br.close();
254
                    fr.close();
255
            } catch(FileNotFoundException ex)        {
256
                    log.info("Error reading the encoding", ex);
257
            } catch (IOException e) {
258
                    log.info("Error reading the encoding", e);
259
                }
260
        }
261

    
262
        /**
263
         * Reads a Web Map Context version 1.1.0. As far as v1.0.0 is a subset of
264
         * v1.1.0 it can be used to read files belonging to 1.0.0 as well.
265
         * @param file, the web map context file.
266
         */
267
        private void parse1_1_0(File file) throws ImportMapContextException {
268
                try {
269
                        readEnconding(file);
270

    
271
                        KXmlParser parser = new KXmlParser();
272
                        parser.setInput(new FileInputStream(file), encoding);
273
                        int tag = parser.nextTag();
274
                        if ( parser.getEventType() != KXmlParser.END_DOCUMENT ) {
275
                                parser.require(KXmlParser.START_TAG, null, WMC_START_TAG);
276
                                while(tag != KXmlParser.END_DOCUMENT) {
277
                                        switch(tag) {
278
                                                case KXmlParser.START_TAG:
279
                                                        if (parser.getName().compareTo(WMC_START_TAG) == 0) {
280
                                                                id = parser.getAttributeValue("", WebMapContextTags.ID);
281
                                                                xmlns = parser.getAttributeValue("", WebMapContextTags.XMLNS);
282
                                                                xmlns_xlink = parser.getAttributeValue("", WebMapContextTags.XMLNS_XLINK);
283
                                                                xmlns_xsi = parser.getAttributeValue("", WebMapContextTags.XMLNS_XSI);
284
                                                                xsi_schemaLocation = parser.getAttributeValue("", WebMapContextTags.XSI_SCHEMA_LOCATION) ;
285
                                                        } else if (parser.getName().compareTo(WebMapContextTags.GENERAL) == 0) {
286
                                                                parseGeneral1_1_0(parser);
287
                                                        } else if (parser.getName().compareTo(WebMapContextTags.LAYER_LIST) == 0) {
288
                                                                int layerListTag = parser.nextTag();
289
                                                                boolean bLayerListEnd = false;
290
                                                                layerList = new ArrayList<FLyrWMS>();
291
                                                                paramsList = new ArrayList<WMSDataParameters>();
292
                                                                while (!bLayerListEnd) {
293
                                                                        switch(layerListTag) {
294
                                                                        case KXmlParser.START_TAG:
295
                                                                                if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
296
                                                                                        FLyrWMS layer = new FLyrWMS();
297
                                                                                        WMSDataParameters dataParameters = new WMSDataParametersImpl();
298
                                                                                        dataParameters.setSRS(srs);
299
                                                                                        parseLayer1_1_0(parser, layer, dataParameters);
300
                                                                                        // will use the mapcontext's bounding box as layer's fullextent
301
                                                                                        IProjection proj =  CRSFactory.getCRS(srs);
302
                                                                                        if (proj == null) {
303
                                                                                                // non supported srs, and cannot continue
304
                                                                                                String msg = Messages.getText("unsupported_crs") + " (" + srs + ")";
305
                                                                                                throw new ImportMapContextException(msg, true);
306
                                                                                        }
307
                                                                                        /*String[] availableSRS = dataParameters.getSRSCode().split(",");
308
                                                                                        ICoordTrans ct = null;
309
                                                                                        String mySRS = null;
310
                                                                                        for (int i = 0; i < availableSRS.length; i++) {
311
                                                                                                mySRS = availableSRS[i];
312
                                                                                                IProjection dstProj = CRSFactory.getCRS(mySRS);
313
                                                                                                if (dstProj != null) {
314
                                                                                                        try{
315
                                                                                                                        ct = proj.getCT(dstProj);
316
                                                                                                                } catch(Exception e) {
317
                                                                                                                        ct = null;
318
                                                                                                                } catch (Error e) {
319
                                                                                                                        ct = null;
320
                                                                                                                }
321
                                                                                                        if (mySRS.equals(srs)) {
322
                                                                                                                break;
323
                                                                                                        }
324
                                                                                                }
325
                                                                                        }
326

327
                                                                                        if (ct != null) {
328
                                                                                                dataParameters.setSRS(mySRS);
329
                                                                                        } else {
330
                                                                                                // can't reproject
331
                                                                                                errorMessages.append("[").
332
                                                                                                                      append(Messages.getText("layer")).
333
                                                                                                                      append(" ").
334
                                                                                                                      append(layer.getName()).
335
                                                                                                                      append("] ").
336
                                                                                                                          append(Messages.getText("cant_reproject_from_any_of")).
337
                                                                                                                          append(" [").append(dataParameters.getSRSCode()).append("] ").
338
                                                                                                                          append(Messages.getText("to")).
339
                                                                                                                          append(srs).
340
                                                                                                                          append("\n");
341
                                                                                                dataParameters.setSRS(srs);
342
                                                                                        }*/
343

    
344
                                                                                        dataParameters.setWmsTransparency(true);
345
                                                                                        layerList.add(layer);
346
                                                                                        paramsList.add(dataParameters);
347
                                                                                } else {
348
                                                                                        log.info("Unrecognized "+ parser.getName());
349
                                                                                }
350
                                                                                break;
351
                                                                        case KXmlParser.END_TAG:
352
                                                                                if (parser.getName().compareTo(WebMapContextTags.LAYER_LIST) == 0) {
353
                                                                                        bLayerListEnd = true;
354
                                                                                }
355
                                                                                break;
356
                                                                        case KXmlParser.TEXT:
357
                                                                                break;
358
                                                                        }
359
                                                                        layerListTag = parser.next();
360
                                                                }
361
                                                        } else if (parser.getName().compareTo(WebMapContextTags.DIMENSION_LIST) == 0) {
362
                                                                log.info("WebMapContext's Dimension not yet implemented");
363
                                                        } else {
364
                                                                log.info("Unrecognized " + parser.getName());
365
                                                        }
366
                                                        break;
367
                                                case KXmlParser.END_TAG:
368
                                                        break;
369
                                                case KXmlParser.TEXT:
370
                                                        break;
371
                                        }
372
                                        tag = parser.next();
373
                                }
374
                                parser.require(KXmlParser.END_DOCUMENT, null, null);
375
                        }
376
                } catch (ImportMapContextException e){
377
                        throw e;
378
                } catch (Exception e) {
379
                        log.debug(Messages.getText("map_context_file_error"), e);
380
                }
381
        }
382

    
383
        /**
384
         * Parses the General tag of a web map context 1.1.0 (and 1.0.0) file
385
         * @param parser
386
         * @throws XmlPullParserException
387
         * @throws IOException
388
         */
389
        private void parseGeneral1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
390
                boolean end = false;
391
            int tag = parser.next();
392
            while (!end) {
393
                    switch(tag) {
394
                        case KXmlParser.START_TAG:
395
                                if (parser.getName().compareTo(WebMapContextTags.WINDOW) == 0) {
396
                                        if (windowSize == null) {
397
                                                        windowSize = new Dimension();
398
                                                }
399
                                                windowSize.setSize(Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH)),
400
                                                                                   Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT)));
401
                                } else if (parser.getName().compareTo(WebMapContextTags.BOUNDING_BOX) == 0) {
402
                                        srs = parser.getAttributeValue("", WebMapContextTags.SRS);
403
                                        double minx = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.X_MIN));
404
                                        double miny = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.Y_MIN));
405
                                        double maxx = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.X_MAX));
406
                                        double maxy = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.Y_MAX));
407
                                        bBox = new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny);
408
                            } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
409
                                        title = parser.nextText();
410
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
411
                                        _abstract = parser.nextText();
412
                                } else if (parser.getName().compareTo(WebMapContextTags.KEYWORD_LIST) == 0) {
413
                                        keywordList = new ArrayList<String>();
414
                                        boolean keywordEnd = false;
415
                                    int keywordTag = parser.next();
416
                                    while (!keywordEnd) {
417
                                            switch(keywordTag) {
418
                                                case KXmlParser.START_TAG:
419
                                                        if (parser.getName().compareTo(WebMapContextTags.KEYWORD) == 0) {
420
                                                                keywordList.add(parser.nextText());
421
                                                        } else {
422
                                                    System.out.println("Unrecognized "+parser.getName());
423
                                                                }
424
                                                                break;
425
                                                 case KXmlParser.END_TAG:
426
                                                        if (parser.getName().compareTo(WebMapContextTags.KEYWORD_LIST) == 0) {
427
                                                                                keywordEnd = true;
428
                                                                        }
429
                                                        break;
430
                                                case KXmlParser.TEXT:
431
                                                        if (parser.getName()!=null) {
432
                                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
433
                                                                        }
434
                                                        break;
435
                                            }
436
                                            keywordTag = parser.next();
437
                                    }
438
                                } else if (parser.getName().compareTo(WebMapContextTags.LOGO_URL) == 0) {
439
                                        logoURLSize = new Dimension(Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH)),
440
                                                                                                Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT)));
441
                                        logoURLFormat = parser.getAttributeValue("", WebMapContextTags.FORMAT.toLowerCase());
442
                                        parser.nextTag();
443
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
444
                                                logoURL = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
445
                                        } else {
446
                                System.out.println("Unrecognized "+parser.getName());
447
                                            }
448
                                } else if (parser.getName().compareTo(WebMapContextTags.DESCRIPTION_URL) == 0) {
449
                                        descriptionURLFormat = parser.getAttributeValue("", WebMapContextTags.FORMAT.toLowerCase());
450
                                        parser.nextTag();
451
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
452
                                                descriptionURL = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
453
                                        } else {
454
                                System.out.println("Unrecognized "+parser.getName());
455
                                            }
456
                                } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_INFORMATION) == 0) {
457
                                        boolean contactInfoEnd = false;
458
                                    int contactInfoTag = parser.next();
459
                                    while (!contactInfoEnd) {
460
                                            switch(contactInfoTag) {
461
                                                case KXmlParser.START_TAG:
462
                                                        if (parser.getName().compareTo(WebMapContextTags.CONTACT_PERSON) == 0) {
463
                                                                contactPerson = parser.nextText();
464
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ORGANIZATION) == 0) {
465
                                                                contactOrganization = parser.nextText();
466
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_POSITION) == 0) {
467
                                                                contactPosition = parser.nextText();
468
                                                        } else if (parser.getName().compareTo(WebMapContextTags.ADDRESS) == 0) {
469
                                                                address = parser.nextText();
470
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CITY) == 0) {
471
                                                                city = parser.nextText();
472
                                                        } else if (parser.getName().compareTo(WebMapContextTags.STATE_OR_PROVINCE) == 0) {
473
                                                                stateOrProvince = parser.nextText();
474
                                                        } else if (parser.getName().compareTo(WebMapContextTags.POSTCODE) == 0) {
475
                                                                postCode = parser.nextText();
476
                                                        } else if (parser.getName().compareTo(WebMapContextTags.COUNTRY) == 0) {
477
                                                                country = parser.nextText();
478
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_VOICE_TELEPHONE) == 0) {
479
                                                                telephone = parser.nextText();
480
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_FACSIMILE_TELEPHONE) == 0) {
481
                                                                fax = parser.nextText();
482
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ELECTRONIC_MAIL_ADDRESS) == 0) {
483
                                                                email = parser.nextText();
484
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_PERSON_PRIMARY) == 0) {
485
                                                                // DO NOTHING
486
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ADDRESS) == 0) {
487
                                                                // DO NOTHING
488
                                                        } else {
489
                                                    System.out.println("Unrecognized "+parser.getName());
490
                                                                }
491
                                                        break;
492
                                                 case KXmlParser.END_TAG:
493
                                                        if (parser.getName().compareTo(WebMapContextTags.CONTACT_INFORMATION) == 0) {
494
                                                                                contactInfoEnd = true;
495
                                                                        }
496
                                                        break;
497
                                                case KXmlParser.TEXT:
498
                                                        if (parser.getName()!=null) {
499
                                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
500
                                                                        }
501
                                                        break;
502
                                            }
503
                                            contactInfoTag = parser.next();
504
                                    }
505
                            } else {
506
                            System.out.println("Unrecognized "+parser.getName());
507
                                        }
508
                                        break;
509
                         case KXmlParser.END_TAG:
510
                                if (parser.getName().compareTo(WebMapContextTags.GENERAL) == 0) {
511
                                                end = true;
512
                                        }
513
                                break;
514
                        case KXmlParser.TEXT:
515
                                if (parser.getName()!=null) {
516
                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
517
                                        }
518
                                break;
519
                    }
520
                    tag = parser.next();
521
            }
522
        }
523

    
524
        @SuppressWarnings("unchecked")
525
        private void parseLayer1_1_0(KXmlParser parser, FLyrWMS layer, WMSDataParameters dataParameters) throws XmlPullParserException, IOException {
526
                boolean end = false;
527
                
528
                String queryable = parser.getAttributeValue("", WebMapContextTags.QUERYABLE);
529
                dataParameters.setQueryable(queryable!=null && (queryable.equals("1") || queryable.toLowerCase().equals("true")));
530
                List<RemoteWMSStyle> styles = new ArrayList<RemoteWMSStyle>();
531
                
532
                String hidden = parser.getAttributeValue("", WebMapContextTags.HIDDEN);
533
                layer.setVisible(hidden == null || !hidden.equals("1") || !hidden.toLowerCase().equals("true"));
534
            int tag = parser.next();
535
            while (!end) {
536
                    switch(tag) {
537
                        case KXmlParser.START_TAG:
538
                                if (parser.getName().compareTo(WebMapContextTags.SERVER) == 0) {
539
                                        String serverTitle = parser.getAttributeValue("", WebMapContextTags.TITLE.toLowerCase());
540
                                        parser.nextTag();
541
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
542
                                                dataParameters.setURI(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF));
543
                                                if (serverTitles == null) {
544
                                                                serverTitles = new Hashtable<String, String>();
545
                                                        }
546
                                            serverTitles.put(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF), serverTitle);
547
                                        }
548
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
549
                                        layer.setName(parser.nextText());
550
                                } else if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
551
                                        dataParameters.setLayerQuery(parser.nextText());
552
                                /* //TODO This case would handle nested layer definitions.
553
                                 *
554
                                 } else if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
555
                                        FLyrWMS sonLayer = parseLayer1_1_0(parser);
556
                                        String q = layer.getLayerQuery();
557
                                        if (q == null) q = "";
558
                                        else q += ",";
559
                                        layer.setLayerQuery( q + sonLayer.getLayerQuery());
560
                                 *
561
                                 */
562
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
563
                                        if (layerAbstracts == null) {
564
                                                        layerAbstracts = new Hashtable();
565
                                                }
566
                                        layerAbstracts.put(layer, parser.nextText());
567
                                } else if (parser.getName().compareTo(WebMapContextTags.SRS) == 0) {
568
                                        String[] srss = parseEPSGList(parser.nextText());
569
                                        if (srsList == null) {
570
                                                srsList = new Hashtable<Object, String[]>();
571
                                                }
572
                                        srsList.put(layer, srss);
573
                                } else if (parser.getName().compareTo(WebMapContextTags.FORMAT_LIST) == 0) {
574
                                        int formatsTag = parser.nextTag();
575
                                        boolean bFormatsEnd = false;
576
                                        ArrayList formats = new ArrayList();
577
                                        while (!bFormatsEnd) {
578
                                                switch (formatsTag) {
579
                                                case KXmlParser.START_TAG:
580
                                                        if (parser.getName().compareTo(WebMapContextTags.FORMAT) == 0) {
581
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
582
                                                                String format = parser.nextText();
583
                                                                if (current!=null && current.equals("1")) {
584
                                                                        dataParameters.setFormat(format);
585
                                                                        }
586
                                                                formats.add(format);
587
                                                        } else {
588
                                                                log.info("Unrecognized " + parser.getName());
589
                                                        }
590
                                                        break;
591
                                                case KXmlParser.END_TAG:
592
                                                        if (parser.getName().compareTo(WebMapContextTags.FORMAT_LIST) == 0) {
593
                                                                        bFormatsEnd = true;
594
                                                                }
595
                                                        break;
596
                                                case KXmlParser.TEXT:
597
                                                        if (parser.getName()!=null) {
598
                                                                log.info("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
599
                                                                }
600
                                                        break;
601
                                                }
602
                                                formatsTag = parser.next();
603
                                        }
604
                                        if (layerFormats == null) {
605
                                                        layerFormats = new Hashtable();
606
                                                }
607
                                        layerFormats.put(layer, formats.toArray(new String[0]));
608

    
609
                                } else if (parser.getName().compareTo(WebMapContextTags.STYLE_LIST) == 0) {
610
                                        int stylesTag = parser.nextTag();
611
                                        boolean bStylesEnd = false;
612
                                        while (!bStylesEnd) {
613
                                                switch (stylesTag) {
614
                                                case KXmlParser.START_TAG:
615
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0) {
616
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
617
                                                                RemoteWMSStyle style = parseStyle1_1_0(parser);
618

    
619
                                                                if (current!=null && current.equals("1") && !style.getName().equals("default")) {
620
                                                                        style.setName("default");
621
                                                                }
622
                                                                styles.add(style);
623
                                                        } else {
624
                                                                System.out.println("Unrecognized "+parser.getName());
625
                                                        }
626
                                                        break;
627
                                                case KXmlParser.END_TAG:
628
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE_LIST) == 0) {
629
                                                                        bStylesEnd = true;
630
                                                                }
631
                                                        break;
632
                                                case KXmlParser.TEXT:
633
                                                        if (parser.getName()!=null) {
634
                                                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
635
                                                                }
636
                                                        break;
637
                                                }
638
                                                stylesTag = parser.next();
639
                                        }
640
                                        if (layerStyles == null) {
641
                                                        layerStyles = new Hashtable();
642
                                                }
643

    
644
                                        layerStyles.put(layer, styles.toArray(new RemoteWMSStyle[0]));
645
                                } else {
646
                                        log.info("Unrecognized " + parser.getName());
647
                                }
648
                                break;
649
                        case KXmlParser.END_TAG:
650
                                if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
651
                                                end = true;
652
                                        }
653
                                break;
654
                        case KXmlParser.TEXT:
655
                                if (parser.getName()!=null) {
656
                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
657
                                        }
658
                                break;
659
                    }
660
                    tag = parser.next();
661
            }
662
            dataParameters.setStyles(styles);
663
        }
664

    
665
        private String[] parseEPSGList(String nextText) {
666
                String[] epsglist = nextText.split(",");
667
                return epsglist;//Arrays.asList(epsglist);
668
        }
669

    
670

    
671
        private RemoteWMSStyle parseStyle1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
672
                boolean end = false;
673
                String styleName = null;
674
                String styleAbstract = null;
675
                String styleTitle = null;
676
                int legendWidth = -1;
677
                int legendHeight = -1;
678
                String legendType = null;
679
                String legendHref = null;
680

    
681
            int tag = parser.next();
682
            while (!end) {
683
                    switch(tag) {
684
                        case KXmlParser.START_TAG:
685
                                if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
686
                                        styleName = parser.nextText();
687
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
688
                                        styleAbstract = parser.nextText();
689
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
690
                                        styleTitle = parser.nextText();
691
                                } else if (parser.getName().compareTo(WebMapContextTags.LEGEND_URL) == 0){
692
                                        legendWidth = Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH));
693
                                        legendHeight = Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT));
694
                                        parser.nextTag();
695
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0 ) {
696
                                                        legendType = parser.getAttributeValue("", WebMapContextTags.XLINK_TYPE);
697
                                                        legendHref = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
698
                                        }
699
                                } else {
700
                            System.out.println("Unrecognized "+parser.getName());
701
                                        }
702
                                break;
703
                         case KXmlParser.END_TAG:
704
                                if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0) {
705
                                                end = true;
706
                                        }
707
                                break;
708
                        case KXmlParser.TEXT:
709
                                if (parser.getName()!=null) {
710
                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
711
                                        }
712
                                break;
713
                    }
714
                    tag = parser.next();
715
            }
716
            
717
            RemoteWMSStyle sty = new RemoteWMSStyle();
718
            sty.setName(styleName);
719
            sty.setTitle(styleTitle);
720
            sty.setStyleAbstract(styleAbstract);
721
            sty.setLegendWidth(legendWidth);
722
            sty.setLegendHeight(legendHeight);
723
            sty.setType(legendType);
724
            sty.setHref(legendHref);
725
            sty.setParent(null);
726
            return sty;
727
        }
728

    
729
        /**
730
         * Creates the Web Map Context (WMC) XML according on the version 1.1.0. Since Web
731
         * WMC 1.0.0 is a subset of WMC 1.1.0 and this method does not produce tags for
732
         * unset values, it can be used to produce WMC 1.0.0, or even to produce
733
         * the deprecated (but still alive) WMC 0.1.4.
734
         * @param v
735
         * @return
736
         */
737
        private String createMapContext1_1_0(DefaultViewDocument v) {
738
                ArrayList layersToExport = getExportableLayers(v);
739

    
740
                XmlBuilder xml = new XmlBuilder();
741
                HashMap<Object, String> xmlAttrs = new HashMap<Object, String>();
742
                xml.setEncoding("ISO-8859-1"); // TODO make it customizable???
743
                xml.writeHeader();
744

    
745
                // <ViewContext>
746
                String viewContextTag;
747
                if (fileVersion.equals("0.1.4")) {
748
                        viewContextTag = WebMapContextTags.VIEW_CONTEXT_0_1_4;
749
                } else {
750
                        viewContextTag = WebMapContextTags.VIEW_CONTEXT;
751
                }
752

    
753
                xml.writeRaw("<!-- " + Messages.getText("created_with") + " gvSIG " + ApplicationLocator.getManager().getVersion() + " -->");
754

    
755
                xmlAttrs.put(WebMapContextTags.VERSION, fileVersion);
756
                xmlAttrs.put(WebMapContextTags.ID, id);
757
                xmlAttrs.put(WebMapContextTags.XMLNS, WebMapContextTags.XMLNS_VALUE);
758
                xmlAttrs.put(WebMapContextTags.XMLNS_XLINK, WebMapContextTags.XMLNS_XLINK_VALUE);
759
                xmlAttrs.put(WebMapContextTags.XMLNS_XSI, WebMapContextTags.XMLNS_XSI_VALUE);
760
                xmlAttrs.put(WebMapContextTags.XSI_SCHEMA_LOCATION, WebMapContextTags.XSI_SCHEMA_LOCATION_VALUE);
761
                xml.openTag(viewContextTag,  xmlAttrs);
762
                xmlAttrs.clear();
763

    
764
                // <General>
765
                xml.openTag(WebMapContextTags.GENERAL);
766

    
767
                // <Window>
768
                if (windowSize!=null) {
769
                        xmlAttrs.put(WebMapContextTags.WIDTH, ((int) windowSize.getWidth())+"");
770
                        xmlAttrs.put(WebMapContextTags.HEIGHT, ((int) windowSize.getHeight())+"");
771
                        xml.writeTag(WebMapContextTags.WINDOW, xmlAttrs);
772
                        xmlAttrs.clear();
773
                }
774
                // </Window>
775

    
776
                // <BoundingBox>
777
                xmlAttrs.put(WebMapContextTags.SRS, v.getProjection().getAbrev());
778
                xmlAttrs.put(WebMapContextTags.X_MIN, bBox.getMinX()+"");
779
                xmlAttrs.put(WebMapContextTags.Y_MIN, bBox.getMinY()+"");
780
                xmlAttrs.put(WebMapContextTags.X_MAX, bBox.getMaxX()+"");
781
                xmlAttrs.put(WebMapContextTags.Y_MAX, bBox.getMaxY()+"");
782
                xml.writeTag(WebMapContextTags.BOUNDING_BOX, xmlAttrs);
783
                xmlAttrs.clear();
784
                // </BoundingBox>
785

    
786
                // <Title>
787
                xml.writeTag(WebMapContextTags.TITLE, title.trim());
788
                // </Title>
789

    
790
                // <Abstract>
791
                if (_abstract != null) {
792
                        xml.writeTag(WebMapContextTags.ABSTRACT, _abstract.trim());
793
                        // </Abstract>
794
                }
795

    
796
                // <LogoURL>
797
                if (logoURL != null) {
798
                        xml.writeTag(WebMapContextTags.LOGO_URL, logoURL.trim());
799
                        // </LogoURL>
800
                }
801

    
802
                // <DescriptionURL>
803
                if (descriptionURL != null) {
804
                        xml.writeTag(WebMapContextTags.DESCRIPTION_URL, descriptionURL.trim());
805
                        // </DescriptionURL>
806
                }
807

    
808
                if (contactInfo) {
809

    
810
                        // <ContactInformation>
811
                        xml.openTag(WebMapContextTags.CONTACT_INFORMATION);
812
                        if (contactPerson != null || contactOrganization != null) {
813

    
814
                                // <ContactPersonPrimary>
815
                                xml.openTag(WebMapContextTags.CONTACT_PERSON_PRIMARY);
816

    
817
                                // <ContactPerson>
818
                                if (contactPerson != null) {
819
                                        xml.writeTag(WebMapContextTags.CONTACT_PERSON, contactPerson.trim());
820
                                        // </ContactPerson>
821
                                }
822

    
823
                                // <ContactOrganization>
824
                                if (contactOrganization != null) {
825
                                        xml.writeTag(WebMapContextTags.CONTACT_ORGANIZATION, contactOrganization.trim());
826
                                        // </ContactOrganization>
827
                                }
828

    
829
                                xml.closeTag();
830
                                // </ContactPersonPrimary>
831
                        }
832
                        xml.closeTag();
833
                        // </ContactInformation>
834

    
835
                        // <ContactPosition>
836
                        if (contactPosition != null) {
837
                                xml.writeTag(WebMapContextTags.CONTACT_POSITION, contactPosition.trim());
838
                                // </ContactPosition>
839
                        }
840

    
841
                        // <ContactAddress>
842
                        if (address != null || city != null || stateOrProvince != null || postCode != null || country != null) {
843
                                xml.openTag(WebMapContextTags.CONTACT_ADDRESS);
844

    
845
                                // <AddressType>
846
                                xml.writeTag(WebMapContextTags.ADDRESS_TYPE, "Postal");
847
                                // </AddressType>
848

    
849
                                // <Address>
850
                                if (address != null) {
851
                                        xml.writeTag(WebMapContextTags.ADDRESS, address.trim());
852
                                        // </Address>
853
                                }
854

    
855
                                // <City>
856
                                if (city != null) {
857
                                        xml.writeTag(WebMapContextTags.CITY, city.trim());
858
                                        // </City>
859
                                }
860

    
861
                                // <StateOrProvince>
862
                                if (stateOrProvince != null) {
863
                                        xml.writeTag(WebMapContextTags.STATE_OR_PROVINCE, stateOrProvince.trim());
864
                                        // </StateOrProvince>
865
                                }
866

    
867
                                // <PostCode>
868
                                if (postCode != null) {
869
                                        xml.writeTag(WebMapContextTags.POSTCODE, postCode.trim());
870
                                        // </PostCode>
871
                                }
872

    
873
                                // <Country>
874
                                if (country != null) {
875
                                        xml.writeTag(WebMapContextTags.COUNTRY, country.trim());
876
                                }
877
                                // </Country>
878
                                xml.closeTag();
879
                        }
880
                        // </ContactAddress>
881

    
882
                        // <ContactVoiceTelephone>
883
                        if (telephone != null) {
884
                                xml.writeTag(WebMapContextTags.CONTACT_VOICE_TELEPHONE, telephone.trim());
885
                                // </ContactVoiceTelephone>
886
                        }
887

    
888
                        // <ContactFacsimileTelephone>
889
                        if (fax != null) {
890
                                xml.writeTag(WebMapContextTags.CONTACT_FACSIMILE_TELEPHONE, fax.trim());
891
                                // </ContactFacsimileTelephone>
892
                        }
893

    
894
                        // <ContactElectronicMailAddress>
895
                        if (email != null) {
896
                                xml.writeTag(WebMapContextTags.CONTACT_ELECTRONIC_MAIL_ADDRESS, email.trim());
897
                                // </ContactElectronicMailAddress>
898
                        }
899
                }
900
                // <KeywordList>
901
                xml.openTag(WebMapContextTags.KEYWORD_LIST);
902
                if (keywordList != null) {
903
                        for (int i = 0; i < keywordList.size(); i++) {
904
                                xml.writeTag(WebMapContextTags.KEYWORD, ((String) keywordList.get(i)).trim());
905
                        }
906
                } else {
907
                        xml.writeTag(WebMapContextTags.KEYWORD, "");
908
                }
909
                xml.closeTag();
910

    
911
                // </KeywordList>
912
                xml.closeTag();
913
                // </General>
914

    
915
                // <LayerList>
916
                xml.openTag(WebMapContextTags.LAYER_LIST);
917
                for (int i = 0; i < layersToExport.size(); i++) {
918
                        xml.writeRaw(((FLyrWMS) layersToExport.get(i)).toMapContext(fileVersion));
919
                }
920
                xml.closeTag();
921
                // </LayerList>
922
                xml.closeTag();
923
                // </ViewContext>
924

    
925
                return xml.getXML();
926
        }
927

    
928
        /**
929
         * Exports the ProjectView passed as parameter to Web Map Context XML compliant
930
         * with the defined specifications for the version set in the fileVersion field.
931
         * @param DefaultViewDocument to be exported
932
         * @return String containing the XML
933
         */
934
        public String toXML(DefaultViewDocument v) {
935
                if (fileVersion.equals("1.1.0") ||
936
                                fileVersion.equals("1.0.0") ||
937
                                fileVersion.equals("0.1.4")) {
938
                        return createMapContext1_1_0(v);
939
                }
940
                return null;
941
        }
942

    
943

    
944
        public static ArrayList getExportableLayers(DefaultViewDocument v) {
945
                ArrayList list = new ArrayList();
946
                FLayers lyrs = v.getMapContext().getLayers();
947
                list.addAll(_getExportableLayers(lyrs));
948
                return list;
949
        }
950

    
951
        private static ArrayList _getExportableLayers(FLayer lyr) {
952
                ArrayList list = new ArrayList();
953
                if (checkType(lyr)) {
954
                        list.add(lyr);
955
                } else {
956
                        if (lyr instanceof FLayers) {
957
                                FLayers lyrs = (FLayers) lyr;
958
                                for (int i = 0; i < lyrs.getLayersCount(); i++) {
959
                                        list.addAll(_getExportableLayers(lyrs.getLayer(i)));
960
                                }
961
                        }
962
                }
963
                return list;
964
        }
965

    
966
        /**
967
         * Checks if the layer is supported by the WebMapContext
968
         * @param lyr
969
         * @return
970
         */
971
        private static boolean checkType(FLayer lyr) {
972
                return supportedLayers.contains(lyr.getClass());
973
        }
974

    
975
        /**
976
         * Searches in the layer tree of the TOC for an ocurrence of any
977
         * exportable layer and returns true if so, or false otherwise.
978
         * @param layer
979
         * @return
980
         */
981
        public static boolean containsExportableLayers(FLayer layer) {
982
                if (checkType(layer)) {
983
                        return true;
984
                }
985

    
986
                if (layer instanceof FLayers) {
987
                        FLayers layers = (FLayers) layer;
988
                        for (int i = 0; i < layers.getLayersCount(); i++) {
989
                                FLayer lyr = layers.getLayer(i);
990
                                if (containsExportableLayers(lyr)) {
991
                                        return true;
992
                                }
993

    
994
                        }
995
                }
996
                return false;
997
        }
998
}