Statistics
| Revision:

gvsig-raster / org.gvsig.raster.wms / branches / org.gvsig.raster.wms_dataaccess_refactoring / org.gvsig.raster.wms.app.wmsclient / src / main / java / org / gvsig / raster / wms / app / wmsclient / wmc / WebMapContext.java @ 2317

History | View | Annotate | Download (35.7 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.HashMap;
35
import java.util.HashSet;
36
import java.util.Hashtable;
37
import java.util.Vector;
38

    
39
import org.cresques.cts.ICoordTrans;
40
import org.cresques.cts.IProjection;
41
import org.gvsig.andami.PluginServices;
42
import org.gvsig.andami.messages.NotificationManager;
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.raster.wms.app.wmsclient.layer.FLyrWMS;
51
import org.gvsig.raster.wms.io.RemoteWMSStyle;
52
import org.kxml2.io.KXmlParser;
53
import org.xmlpull.v1.XmlPullParserException;
54

    
55

    
56
/**
57
 * Class that loads and produces WebMapContext files and holds its attributes.
58
 *
59
 * You can create a blank WebMapContext instance using the default constructor
60
 * or an already initialized instance by specifying a source file. In the last
61
 * case the file will be readed and the values loaded an holded by the instance.
62
 *
63
 * You can get the equivalent WebMapContext XML document by calling the method
64
 * getXML() supplying the ProjectView that you want to export and depending on
65
 * the value of the fileVersion field (currently you can use "1.1.0" (default),
66
 * "1.0.0" or "0.4.1" to specify the destination document version.
67
 *
68
 * @author jaume dominguez faus - jaume.dominguez@iver.es
69
 */
70
public class WebMapContext {
71
        public final static String FILE_EXTENSION = ".cml";
72

    
73
        static final ArrayList<String> supportedVersions = new ArrayList<String>();
74
        static public final ArrayList<String> exportVersions    = new ArrayList<String>();
75
        static private HashSet supportedLayers = new HashSet();
76
        private File mapContextFile;
77
        private String encoding = "UTF-8";
78
        private String WMC_START_TAG;
79

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

    
111
        private StringBuffer errorMessages;
112

    
113
        /**
114
         * list of FLyrWMS.
115
         */
116
        ArrayList<FLyrWMS> layerList = null;
117

    
118
        /**
119
         * key: server URL (URL)
120
         * value: server title (String)
121
         */
122
        Hashtable serverTitles = null;
123

    
124
        /**
125
         * key: layer FLyrWMS
126
         * value: layer abstract (String)
127
         */
128
        Hashtable layerAbstracts = null;
129

    
130
        /**
131
         * key: layer FLyrWMS
132
         * value: layer formats (String[])
133
         */
134
        Hashtable layerFormats = null;
135

    
136
        /**
137
         * key: layer FLyrWMS
138
         * value: styles (FMapWMSStyle[])
139
         */
140
        Hashtable layerStyles = null;
141

    
142

    
143
        static {
144
                supportedVersions.add("1.1.0");
145
                supportedVersions.add("1.0.0");
146
                supportedVersions.add("0.1.4");
147
        }
148

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

    
155
        static {
156
                supportedLayers.add(FLyrWMS.class);
157
        }
158

    
159

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

    
184
                                // Once parsed, check errors
185
                                if (errorMessages.length()>0) {
186
                                        throw new ImportMapContextException(errorMessages.toString(), false);
187
                                }
188
                        } else {
189
                                throw new UnsupportedVersionLayerException(file.getName(),null);
190
                        }
191
                }
192
        }
193

    
194

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

    
205
        /**
206
         * Reads the header of the Weg Map Context file and determines which version
207
         * it belongs to.
208
         * @return String.
209
         */
210
        private String getVersion() {
211
                if (fileVersion == null) {
212
                        String v = null;
213
                        try {
214
                                FileReader fr = new FileReader(mapContextFile);
215
                                KXmlParser parser = new KXmlParser();
216
                                parser.setInput(fr);
217
                                parser.nextTag();
218
                            if ( parser.getEventType() != KXmlParser.END_DOCUMENT )        {
219
                                    if ((parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT) == 0) ||
220
                                             parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT_0_1_4) == 0) {
221
                                            v = parser.getAttributeValue("", WebMapContextTags.VERSION);
222
                                    }
223
                            }
224
                        } catch (FileNotFoundException fnfEx) {
225
                        } catch (XmlPullParserException xmlEx) {
226
                                xmlEx.printStackTrace();
227
                        } catch (IOException e) {
228
                        }
229
                        fileVersion = v;
230
                }
231
                return fileVersion;
232
        }
233

    
234
        /**
235
         * Reads a Web Map Context version 1.1.0. As far as v1.0.0 is a subset of
236
         * v1.1.0 it can be used to read files belonging to 1.0.0 as well.
237
         * @param file, the web map context file.
238
         */
239
        private void parse1_1_0(File file) throws ImportMapContextException {
240
                try {
241
                        FileReader fr;
242
                        try
243
                    {
244
                                fr = new FileReader(file);
245
                            BufferedReader br = new BufferedReader(fr);
246
                            char[] buffer = new char[100];
247
                            br.read(buffer);
248
                            StringBuffer st = new StringBuffer(new String(buffer));
249
                            String searchText = "encoding=\"";
250
                            int index = st.indexOf(searchText);
251
                            if (index>-1) {
252
                                    st.delete(0, index+searchText.length());
253
                                    encoding = st.substring(0, st.indexOf("\""));
254
                            }
255
                    } catch(FileNotFoundException ex)        {
256
                            ex.printStackTrace();
257
                    } catch (IOException e) {
258
                                e.printStackTrace();
259
                        }
260

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

    
318
                                                                                        if (ct != null) {
319
                                                                                                // I've found a supported projection
320
                                                                                                //layer.setFullExtent(ct.convert(bBox));
321
                                                                                                layer.getParameters().setSRS(mySRS);
322
                                                                                        } else {
323
                                                                                                // can't reproject
324
                                                                                                errorMessages.append("[").
325
                                                                                                                      append(PluginServices.getText(this, "layer")).
326
                                                                                                                      append(" ").
327
                                                                                                                      append(layer.getName()).
328
                                                                                                                      append("] ").
329
                                                                                                                          append(PluginServices.getText(this, "cant_reproject_from_any_of")).
330
                                                                                                                          append(" [").append(layer.getParameters().getSRSCode()).append("] ").
331
                                                                                                                          append(PluginServices.getText(this, "to")).
332
                                                                                                                          append(srs).
333
                                                                                                                          append("\n");
334

    
335
                                                                                                /*
336
                                                                                                 * will use view's projection and bounding box
337
                                                                                                 * strictly this is incorrect but, at least it allows
338
                                                                                                 * the user to recover by changin layer properties.
339
                                                                                                 */
340
                                                                                                //layer.setFullExtent(bBox);
341
                                                                                                layer.getParameters().setSRS(srs);
342
                                                                                        }
343

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

    
385
        }
386

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

    
528
        @SuppressWarnings("unchecked")
529
        private FLyrWMS parseLayer1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
530
                boolean end = false;
531
                FLyrWMS layer = new FLyrWMS();
532

    
533
                String queryable = parser.getAttributeValue("", WebMapContextTags.QUERYABLE);
534
                layer.getParameters().setQueryable(queryable!=null && (queryable.equals("1") || queryable.toLowerCase().equals("true")));
535

    
536
                String hidden = parser.getAttributeValue("", WebMapContextTags.HIDDEN);
537
                layer.setVisible(hidden==null || !hidden.equals("1") || !hidden.toLowerCase().equals("true"));
538
            int tag = parser.next();
539
            while (!end) {
540
                    switch(tag) {
541
                        case KXmlParser.START_TAG:
542
                                if (parser.getName().compareTo(WebMapContextTags.SERVER) == 0) {
543
                                        String serverTitle = parser.getAttributeValue("", WebMapContextTags.TITLE.toLowerCase());
544
                                        parser.nextTag();
545
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
546
                                                layer.getParameters().setURI(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF));
547
                                                if (serverTitles == null) {
548
                                                                serverTitles = new Hashtable();
549
                                                        }
550
                                            serverTitles.put(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF), serverTitle);
551
                                        }
552
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
553
                                        layer.setName(parser.nextText());
554
                                } else if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
555
                                        layer.getParameters().setLayerQuery(parser.nextText());
556
                                /* //TODO This case would handle nested layer definitions.
557
                                 *
558
                                 } else if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
559
                                        FLyrWMS sonLayer = parseLayer1_1_0(parser);
560
                                        String q = layer.getLayerQuery();
561
                                        if (q == null) q = "";
562
                                        else q += ",";
563
                                        layer.setLayerQuery( q + sonLayer.getLayerQuery());
564
                                 *
565
                                 */
566
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
567
                                        if (layerAbstracts == null) {
568
                                                        layerAbstracts = new Hashtable();
569
                                                }
570
                                        layerAbstracts.put(layer, parser.nextText());
571
                                } else if (parser.getName().compareTo(WebMapContextTags.SRS) == 0) {
572
                                        layer.getParameters().setSRS(parser.nextText());
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
                                                                                layer.getParameters().setFormat(format);
585
                                                                        }
586
                                                                formats.add(format);
587
                                                        } else {
588
                                                                System.out.println("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
                                                                        System.out.println("[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
                                        ArrayList styles = new ArrayList();
613
                                        while (!bStylesEnd) {
614
                                                switch (stylesTag) {
615
                                                case KXmlParser.START_TAG:
616
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0) {
617
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
618
                                                                RemoteWMSStyle style = parseStyle1_1_0(parser);
619

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

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

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

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

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

    
738
                XmlBuilder xml = new XmlBuilder();
739
                HashMap xmlAttrs = new HashMap();
740
                xml.setEncoding("ISO-8859-1"); // TODO make it customizable???
741
                xml.writeHeader();
742

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

    
751
                xml.writeRaw("<!-- "+PluginServices.getText(this, "created_with")+" gvSIG "+ ApplicationLocator.getManager().getVersion() +" -->");
752

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

    
762
                        // <General>
763
                        xml.openTag(WebMapContextTags.GENERAL);
764

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

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

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

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

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

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

    
806
                                if (contactInfo) {
807

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

    
812
                                                // <ContactPersonPrimary>
813
                                                xml.openTag(WebMapContextTags.CONTACT_PERSON_PRIMARY);
814

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
909
                                // </KeywordList>
910
                        xml.closeTag();
911
                        // </General>
912

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

    
923
                return xml.getXML();
924
        }
925

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

    
941

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

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

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

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

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

    
992
                        }
993
                }
994
                return false;
995
        }
996
}