Statistics
| Revision:

root / trunk / extensions / extWMS / src / com / iver / cit / gvsig / wmc / WebMapContext.java @ 9554

History | View | Annotate | Download (36.5 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
/* CVS MESSAGES:
43
*
44
* $Id: WebMapContext.java 9554 2007-01-08 07:57:34Z jaume $
45
* $Log$
46
* Revision 1.8  2007-01-08 07:57:34  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.7  2006/09/26 14:41:48  jaume
50
* *** empty log message ***
51
*
52
* Revision 1.6  2006/09/25 10:23:26  caballero
53
* Projection
54
*
55
* Revision 1.5  2006/09/15 10:44:24  caballero
56
* extensibilidad de documentos
57
*
58
* Revision 1.4  2006/07/21 10:31:05  jaume
59
* *** empty log message ***
60
*
61
* Revision 1.3  2006/05/24 16:36:28  jaume
62
* *** empty log message ***
63
*
64
* Revision 1.2  2006/05/12 07:47:39  jaume
65
* removed unnecessary imports
66
*
67
* Revision 1.1  2006/05/03 07:51:21  jaume
68
* *** empty log message ***
69
*
70
* Revision 1.10  2006/05/02 15:57:44  jaume
71
* Few better javadoc
72
*
73
* Revision 1.9  2006/04/25 11:40:56  jaume
74
* *** empty log message ***
75
*
76
* Revision 1.8  2006/04/25 10:01:56  jaume
77
* fixed extend bug when importing
78
*
79
* Revision 1.7  2006/04/21 12:46:53  jaume
80
* *** empty log message ***
81
*
82
* Revision 1.6  2006/04/21 11:53:50  jaume
83
* *** empty log message ***
84
*
85
* Revision 1.5  2006/04/21 11:02:25  jaume
86
* few translations
87
*
88
* Revision 1.4  2006/04/21 10:27:32  jaume
89
* exporting now supported
90
*
91
* Revision 1.3  2006/04/20 17:11:54  jaume
92
* Attempting to export
93
*
94
* Revision 1.2  2006/04/19 16:34:29  jaume
95
* *** empty log message ***
96
*
97
* Revision 1.1  2006/04/19 07:57:29  jaume
98
* *** empty log message ***
99
*
100
* Revision 1.1  2006/04/12 17:10:53  jaume
101
* *** empty log message ***
102
*
103
*
104
*/
105
package com.iver.cit.gvsig.wmc;
106

    
107
import java.awt.Dimension;
108
import java.awt.geom.Rectangle2D;
109
import java.io.BufferedReader;
110
import java.io.File;
111
import java.io.FileInputStream;
112
import java.io.FileNotFoundException;
113
import java.io.FileReader;
114
import java.io.IOException;
115
import java.net.URL;
116
import java.util.ArrayList;
117
import java.util.HashMap;
118
import java.util.HashSet;
119
import java.util.Hashtable;
120
import java.util.Vector;
121

    
122
import org.cresques.cts.ICoordTrans;
123
import org.cresques.cts.IProjection;
124
import org.kxml2.io.KXmlParser;
125
import org.xmlpull.v1.XmlPullParserException;
126

    
127
import com.iver.andami.PluginServices;
128
import com.iver.andami.messages.NotificationManager;
129
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
130
import com.iver.cit.gvsig.fmap.drivers.UnsupportedVersionException;
131
import com.iver.cit.gvsig.fmap.exceptions.ImportMapContextException;
132
import com.iver.cit.gvsig.fmap.layers.FLayer;
133
import com.iver.cit.gvsig.fmap.layers.FLayers;
134
import com.iver.cit.gvsig.fmap.layers.FLyrWMS;
135
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode;
136
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode.FMapWMSStyle;
137
import com.iver.cit.gvsig.fmap.rendering.XmlBuilder;
138
import com.iver.cit.gvsig.project.Project;
139
import com.iver.cit.gvsig.project.documents.view.ProjectView;
140

    
141
/**
142
 * Class that loads and produces WebMapContext files and holds its attributes.
143
 *
144
 * You can create a blank WebMapContext instance using the default constructor
145
 * or an already initialized instance by specifying a source file. In the last
146
 * case the file will be readed and the values loaded an holded by the instance.
147
 *
148
 * You can get the equivalent WebMapContext XML document by calling the method
149
 * getXML() supplying the ProjectView that you want to export and depending on
150
 * the value of the fileVersion field (currently you can use "1.1.0" (default),
151
 * "1.0.0" or "0.4.1" to specify the destination document version.
152
 *
153
 * @author jaume dominguez faus - jaume.dominguez@iver.es
154
 */
155
public class WebMapContext {
156
        public final static String FILE_EXTENSION = ".cml";
157

    
158
        static final ArrayList supportedVersions = new ArrayList();
159
        static public final ArrayList exportVersions    = new ArrayList();
160
        static private HashSet supportedLayers = new HashSet();
161
        private File mapContextFile;
162
        private String encoding = "UTF-8";
163
        private String WMC_START_TAG;
164

    
165
        // MapContext stuff
166
        public String fileVersion = null;
167
        public Dimension windowSize = null;
168
        public String srs = null;
169
        public Rectangle2D bBox = null;
170
        public String title = null;
171
        public String id = null;
172
        public String xmlns = null;
173
        public String xmlns_xlink = null;
174
        public String xmlns_xsi = null;;
175
        public String xsi_schemaLocation = null;
176
        public String _abstract = null;
177
        public ArrayList keywordList = null;
178
        public Dimension logoURLSize = null;
179
        public String logoURLFormat = null;
180
        public String logoURL = null;
181
        public String descriptionURLFormat = null;
182
        public String descriptionURL = null;
183
        public boolean contactInfo = false;
184
        public String contactPerson = null;
185
        public String contactOrganization = null;
186
        public String contactPosition = null;
187
        public String address = null;
188
        public String city = null;
189
        public String stateOrProvince = null;
190
        public String postCode = null;
191
        public String country = null;
192
        public String telephone = null;
193
        public String fax = null;
194
        public String email = null;
195

    
196
        private StringBuffer errorMessages;
197

    
198
        /**
199
         * list of FLyrWMS.
200
         */
201
        ArrayList layerList = null;
202

    
203
        /**
204
         * key: server URL (URL)
205
         * value: server title (String)
206
         */
207
        Hashtable serverTitles = null;
208

    
209
        /**
210
         * key: layer FLyrWMS
211
         * value: layer abstract (String)
212
         */
213
        Hashtable layerAbstracts = null;
214

    
215
        /**
216
         * key: layer FLyrWMS
217
         * value: layer formats (String[])
218
         */
219
        Hashtable layerFormats = null;
220

    
221
        /**
222
         * key: layer FLyrWMS
223
         * value: styles (FMapWMSStyle[])
224
         */
225
        Hashtable layerStyles = null;
226

    
227

    
228
        static {
229
                supportedVersions.add("1.1.0");
230
                supportedVersions.add("1.0.0");
231
                supportedVersions.add("0.1.4");
232
        }
233

    
234
        static {
235
                exportVersions.add("1.1.0");
236
                exportVersions.add("1.0.0");
237
                exportVersions.add("0.1.4");
238
        }
239

    
240
        static {
241
                supportedLayers.add(FLyrWMS.class);
242
        }
243

    
244

    
245
        /**
246
         * Initializes the WebMapContext properties from the values in the WebMapContext (.cml)
247
         * file passed in the argument.
248
         * @param file
249
         * @throws UnsupportedVersionException
250
         * @throws ImportMapContextException
251
         */
252
        public void readFile(File file) throws UnsupportedVersionException, ImportMapContextException {
253
                this.mapContextFile = file;
254
                errorMessages = new StringBuffer();
255
                if (getVersion()!=null) {
256
                        if (supportedVersions.contains(getVersion())) {
257
                                WMC_START_TAG = WebMapContextTags.VIEW_CONTEXT;
258
                                if (getVersion().equals("0.1.4")) {
259
                                        WMC_START_TAG = WebMapContextTags.VIEW_CONTEXT_0_1_4;
260
                                        parse1_1_0(file);
261
                                } else if (getVersion().equals("1.1.0")) {
262
                                        parse1_1_0(file);
263
                                } else if (getVersion().equals("1.0.0")) {
264
                                        parse1_1_0(file);
265
                                } else {
266
                                        parseDefaultVersion(file);
267
                                }
268

    
269
                                // Once parsed, check errors
270
                                if (errorMessages.length()>0)
271
                                        throw new ImportMapContextException(errorMessages.toString(), false);
272
                        } else throw new UnsupportedVersionException(PluginServices.getText(this, "file_version")+": "+getVersion());
273
                }
274
        }
275

    
276

    
277
        /**
278
         * If no version was recognized then will parse the default one which is supposed
279
         * to be the best available.
280
         * @param file
281
         */
282
        private void parseDefaultVersion(File file) {
283
                parse1_1_0(file);
284
        }
285

    
286
        /**
287
         * Reads the header of the Weg Map Context file and determines which version
288
         * it belongs to.
289
         * @return String.
290
         */
291
        private String getVersion() {
292
                if (fileVersion == null) {
293
                        String v = null;
294
                        try {
295
                                FileReader fr = new FileReader(mapContextFile);
296
                                KXmlParser parser = new KXmlParser();
297
                                parser.setInput(fr);
298
                                parser.nextTag();
299
                            if ( parser.getEventType() != KXmlParser.END_DOCUMENT )        {
300
                                    if ((parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT) == 0) ||
301
                                             parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT_0_1_4) == 0) {
302
                                            v = parser.getAttributeValue("", WebMapContextTags.VERSION);
303
                                    }
304
                            }
305
                        } catch (FileNotFoundException fnfEx) {
306
                        } catch (XmlPullParserException xmlEx) {
307
                                xmlEx.printStackTrace();
308
                        } catch (IOException e) {
309
                        }
310
                        fileVersion = v;
311
                }
312
                return fileVersion;
313
        }
314

    
315
        /**
316
         * Reads a Web Map Context version 1.1.0. As far as v1.0.0 is a subset of
317
         * v1.1.0 it can be used to read files belonging to 1.0.0 as well.
318
         * @param file, the web map context file.
319
         */
320
        private void parse1_1_0(File file) {
321
                try {
322
                        FileReader fr;
323
                        try
324
                    {
325
                                fr = new FileReader(file);
326
                            BufferedReader br = new BufferedReader(fr);
327
                            char[] buffer = new char[100];
328
                            br.read(buffer);
329
                            StringBuffer st = new StringBuffer(new String(buffer));
330
                            String searchText = "encoding=\"";
331
                            int index = st.indexOf(searchText);
332
                            if (index>-1) {
333
                                    st.delete(0, index+searchText.length());
334
                                    encoding = st.substring(0, st.indexOf("\""));
335
                            }
336
                    } catch(FileNotFoundException ex)        {
337
                            ex.printStackTrace();
338
                    } catch (IOException e) {
339
                                e.printStackTrace();
340
                        }
341

    
342
                        fr = new FileReader(file);
343
                        KXmlParser parser = new KXmlParser();
344
                        parser.setInput(new FileInputStream(file), encoding);
345
                        int tag = parser.nextTag();
346
                        if ( parser.getEventType() != KXmlParser.END_DOCUMENT )
347
                        {
348
                                parser.require(KXmlParser.START_TAG, null, WMC_START_TAG);
349
                                while(tag != KXmlParser.END_DOCUMENT) {
350
                                        switch(tag) {
351
                                                case KXmlParser.START_TAG:
352
                                                        if (parser.getName().compareTo(WMC_START_TAG) == 0) {
353
                                                                id = parser.getAttributeValue("", WebMapContextTags.ID);
354
                                                                xmlns = parser.getAttributeValue("", WebMapContextTags.XMLNS);
355
                                                                xmlns_xlink = parser.getAttributeValue("", WebMapContextTags.XMLNS_XLINK);
356
                                                                xmlns_xsi = parser.getAttributeValue("", WebMapContextTags.XMLNS_XSI);
357
                                                                xsi_schemaLocation = parser.getAttributeValue("", WebMapContextTags.XSI_SCHEMA_LOCATION) ;
358
                                                        } else if (parser.getName().compareTo(WebMapContextTags.GENERAL) == 0) {
359
                                                                parseGeneral1_1_0(parser);
360
                                                        } else if (parser.getName().compareTo(WebMapContextTags.LAYER_LIST) == 0) {
361
                                                                int layerListTag = parser.nextTag();
362
                                                                boolean bLayerListEnd = false;
363
                                                                layerList = new ArrayList();
364
                                                                while (!bLayerListEnd) {
365
                                                                        switch(layerListTag) {
366
                                                                        case KXmlParser.START_TAG:
367
                                                                                if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
368
                                                                                        FLyrWMS layer = parseLayer1_1_0(parser);
369
                                                                                        // will use the mapcontext's bounding box as layer's fullextent
370
                                                                                        IProjection proj =  CRSFactory.getCRS(srs);
371
                                                                                        if (proj == null) {
372
                                                                                                // non supported srs, and cannot continue
373
                                                                                                String msg = PluginServices.getText(this, "unsupported_crs") +
374
                                                                                                                         " (" + srs + ")";
375
                                                                                                throw new ImportMapContextException(msg, true);
376
                                                                                        }
377
                                                                                        String[] availableSRS = layer.getSRS().split(",");
378
                                                                                        ICoordTrans ct = null;
379
                                                                                        String mySRS = null;
380
                                                                                        for (int i = 0; i < availableSRS.length; i++) {
381
                                                                                                mySRS = availableSRS[i];
382
                                                                                                IProjection dstProj = CRSFactory.getCRS(mySRS);
383
                                                                                                if (dstProj != null) {
384
                                                                                                        ct = proj.getCT(dstProj);
385
                                                                                                        if (mySRS.equals(srs)) {
386
                                                                                                                // this is the most suitable SRS,
387
                                                                                                                break;
388
                                                                                                        }
389
                                                                                                }
390
                                                                                        }
391

    
392
                                                                                        if (ct != null) {
393
                                                                                                // I've found a supported projection
394
                                                                                                layer.setFullExtent(ct.convert(bBox));
395
                                                                                                layer.setSRS(mySRS);
396
                                                                                        } else {
397
                                                                                                // can't reproject
398
                                                                                                errorMessages.append("[").
399
                                                                                                                      append(PluginServices.getText(this, "layer")).
400
                                                                                                                      append(" ").
401
                                                                                                                      append(layer.getName()).
402
                                                                                                                      append("] ").
403
                                                                                                                          append(PluginServices.getText(this, "cant_reproject_from_any_of")).
404
                                                                                                                          append(" [").append(layer.getSRS()).append("] ").
405
                                                                                                                          append(PluginServices.getText(this, "to")).
406
                                                                                                                          append(srs).
407
                                                                                                                          append("\n");
408

    
409
                                                                                                /*
410
                                                                                                 * will use view's projection and bounding box
411
                                                                                                 * strictly this is incorrect but, at least it allows
412
                                                                                                 * the user to recover by changin layer properties.
413
                                                                                                 */
414
                                                                                                layer.setFullExtent(bBox);
415
                                                                                                layer.setSRS(srs);
416
                                                                                        }
417

    
418
                                                                                        layer.setWmsTransparency(true);
419
                                                                                        layerList.add(layer);
420
                                                                                } else {
421
                                                                    System.out.println("Unrecognized "+parser.getName());
422
                                                                                }
423
                                                                                break;
424
                                                                        case KXmlParser.END_TAG:
425
                                                                                if (parser.getName().compareTo(WebMapContextTags.LAYER_LIST) == 0)
426
                                                                                        bLayerListEnd = true;
427
                                                                                break;
428
                                                                        case KXmlParser.TEXT:
429
                                                                                //System.out.println("[TEXT]["+kxmlParser.getText()+"]");
430
                                                                                break;
431
                                                                        }
432
                                                                        layerListTag = parser.next();
433
                                                                }
434
                                                        } else if (parser.getName().compareTo(WebMapContextTags.DIMENSION_LIST) == 0) {
435
                                                                // TODO
436
                                                                System.out.println("WebMapContext's Dimension not yet implemented");
437
                                                        } else {
438
                                            System.out.println("Unrecognized "+parser.getName());
439
                                                        }
440
                                                        break;
441
                                                case KXmlParser.END_TAG:
442
                                                        break;
443
                                                case KXmlParser.TEXT:
444
                                                        //System.out.println("[TEXT]["+kxmlParser.getText()+"]");
445
                                                        break;
446
                                        }
447
                                        tag = parser.next();
448
                                }
449
                                parser.require(KXmlParser.END_DOCUMENT, null, null);
450
                        }
451
                } catch (Exception e) {
452
                        NotificationManager.addError(PluginServices.getText(this, "map_context_file_error"),e);
453
                        e.printStackTrace();
454
                }
455

    
456
        }
457

    
458
        /**
459
         * Parses the General tag of a web map context 1.1.0 (and 1.0.0) file
460
         * @param parser
461
         * @throws XmlPullParserException
462
         * @throws IOException
463
         */
464
        private void parseGeneral1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
465
                boolean end = false;
466
            int tag = parser.next();
467
            while (!end) {
468
                    switch(tag) {
469
                        case KXmlParser.START_TAG:
470
                                if (parser.getName().compareTo(WebMapContextTags.WINDOW) == 0) {
471
                                        if (windowSize == null) windowSize = new Dimension();
472
                                                windowSize.setSize(Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH)),
473
                                                                                   Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT)));
474
                                } else if (parser.getName().compareTo(WebMapContextTags.BOUNDING_BOX) == 0) {
475
                                        srs = parser.getAttributeValue("", WebMapContextTags.SRS);
476
                                        double minx = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.X_MIN));
477
                                        double miny = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.Y_MIN));
478
                                        double maxx = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.X_MAX));
479
                                        double maxy = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.Y_MAX));
480
                                        bBox = new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny);
481
                            } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
482
                                        title = parser.nextText();
483
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
484
                                        _abstract = parser.nextText();
485
                                } else if (parser.getName().compareTo(WebMapContextTags.KEYWORD_LIST) == 0) {
486
                                        keywordList = new ArrayList();
487
                                        boolean keywordEnd = false;
488
                                    int keywordTag = parser.next();
489
                                    while (!keywordEnd) {
490
                                            switch(keywordTag) {
491
                                                case KXmlParser.START_TAG:
492
                                                        if (parser.getName().compareTo(WebMapContextTags.KEYWORD) == 0) {
493
                                                                keywordList.add(parser.nextText());
494
                                                        } else {
495
                                                    System.out.println("Unrecognized "+parser.getName());
496
                                                                }
497
                                                                break;
498
                                                 case KXmlParser.END_TAG:
499
                                                        if (parser.getName().compareTo(WebMapContextTags.KEYWORD_LIST) == 0)
500
                                                                keywordEnd = true;
501
                                                        break;
502
                                                case KXmlParser.TEXT:
503
                                                        if (parser.getName()!=null)
504
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
505
                                                        break;
506
                                            }
507
                                            keywordTag = parser.next();
508
                                    }
509
                                } else if (parser.getName().compareTo(WebMapContextTags.LOGO_URL) == 0) {
510
                                        logoURLSize = new Dimension(Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH)),
511
                                                                                                Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT)));
512
                                        logoURLFormat = parser.getAttributeValue("", WebMapContextTags.FORMAT.toLowerCase());
513
                                        parser.nextTag();
514
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
515
                                                logoURL = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
516
                                        } else {
517
                                System.out.println("Unrecognized "+parser.getName());
518
                                            }
519
                                } else if (parser.getName().compareTo(WebMapContextTags.DESCRIPTION_URL) == 0) {
520
                                        descriptionURLFormat = parser.getAttributeValue("", WebMapContextTags.FORMAT.toLowerCase());
521
                                        parser.nextTag();
522
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
523
                                                descriptionURL = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
524
                                        } else {
525
                                System.out.println("Unrecognized "+parser.getName());
526
                                            }
527
                                } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_INFORMATION) == 0) {
528
                                        boolean contactInfoEnd = false;
529
                                    int contactInfoTag = parser.next();
530
                                    while (!contactInfoEnd) {
531
                                            switch(contactInfoTag) {
532
                                                case KXmlParser.START_TAG:
533
                                                        if (parser.getName().compareTo(WebMapContextTags.CONTACT_PERSON) == 0) {
534
                                                                contactPerson = parser.nextText();
535
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ORGANIZATION) == 0) {
536
                                                                contactOrganization = parser.nextText();
537
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_POSITION) == 0) {
538
                                                                contactPosition = parser.nextText();
539
                                                        } else if (parser.getName().compareTo(WebMapContextTags.ADDRESS) == 0) {
540
                                                                address = parser.nextText();
541
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CITY) == 0) {
542
                                                                city = parser.nextText();
543
                                                        } else if (parser.getName().compareTo(WebMapContextTags.STATE_OR_PROVINCE) == 0) {
544
                                                                stateOrProvince = parser.nextText();
545
                                                        } else if (parser.getName().compareTo(WebMapContextTags.POSTCODE) == 0) {
546
                                                                postCode = parser.nextText();
547
                                                        } else if (parser.getName().compareTo(WebMapContextTags.COUNTRY) == 0) {
548
                                                                country = parser.nextText();
549
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_VOICE_TELEPHONE) == 0) {
550
                                                                telephone = parser.nextText();
551
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_FACSIMILE_TELEPHONE) == 0) {
552
                                                                fax = parser.nextText();
553
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ELECTRONIC_MAIL_ADDRESS) == 0) {
554
                                                                email = parser.nextText();
555
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_PERSON_PRIMARY) == 0) {
556
                                                                // DO NOTHING
557
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ADDRESS) == 0) {
558
                                                                // DO NOTHING
559
                                                        } else {
560
                                                    System.out.println("Unrecognized "+parser.getName());
561
                                                                }
562
                                                        break;
563
                                                 case KXmlParser.END_TAG:
564
                                                        if (parser.getName().compareTo(WebMapContextTags.CONTACT_INFORMATION) == 0)
565
                                                                contactInfoEnd = true;
566
                                                        break;
567
                                                case KXmlParser.TEXT:
568
                                                        if (parser.getName()!=null)
569
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
570
                                                        break;
571
                                            }
572
                                            contactInfoTag = parser.next();
573
                                    }
574
                            } else {
575
                            System.out.println("Unrecognized "+parser.getName());
576
                                        }
577
                                        break;
578
                         case KXmlParser.END_TAG:
579
                                if (parser.getName().compareTo(WebMapContextTags.GENERAL) == 0)
580
                                        end = true;
581
                                break;
582
                        case KXmlParser.TEXT:
583
                                if (parser.getName()!=null)
584
                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
585
                                break;
586
                    }
587
                    tag = parser.next();
588
            }
589
        }
590

    
591
        private FLyrWMS parseLayer1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
592
                boolean end = false;
593
                FLyrWMS layer = new FLyrWMS();
594

    
595
                String queryable = parser.getAttributeValue("", WebMapContextTags.QUERYABLE);
596
                layer.setQueryable(queryable!=null && (queryable.equals("1") || queryable.toLowerCase().equals("true")));
597

    
598
                String hidden = parser.getAttributeValue("", WebMapContextTags.HIDDEN);
599
                layer.setVisible(hidden==null || !hidden.equals("1") || !hidden.toLowerCase().equals("true"));
600
            int tag = parser.next();
601
            while (!end) {
602
                    switch(tag) {
603
                        case KXmlParser.START_TAG:
604
                                if (parser.getName().compareTo(WebMapContextTags.SERVER) == 0) {
605
                                        String serverTitle = parser.getAttributeValue("", WebMapContextTags.TITLE.toLowerCase());
606
                                        parser.nextTag();
607
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
608
                                                layer.setHost(new URL(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF)));
609
                                                if (serverTitles == null)
610
                                                    serverTitles = new Hashtable();
611
                                            serverTitles.put(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF), serverTitle);
612
                                        }
613
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
614
                                        layer.setName(parser.nextText());
615
                                } else if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
616
                                        layer.setLayerQuery(parser.nextText());
617
                                /* //TODO This case would handle nested layer definitions.
618
                                 *
619
                                 } else if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
620
                                        FLyrWMS sonLayer = parseLayer1_1_0(parser);
621
                                        String q = layer.getLayerQuery();
622
                                        if (q == null) q = "";
623
                                        else q += ",";
624
                                        layer.setLayerQuery( q + sonLayer.getLayerQuery());
625
                                 *
626
                                 */
627
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
628
                                        if (layerAbstracts == null)
629
                                                layerAbstracts = new Hashtable();
630
                                        layerAbstracts.put(layer, parser.nextText());
631
                                } else if (parser.getName().compareTo(WebMapContextTags.SRS) == 0) {
632
                                        layer.setSRS(parser.nextText());
633
                                } else if (parser.getName().compareTo(WebMapContextTags.FORMAT_LIST) == 0) {
634
                                        int formatsTag = parser.nextTag();
635
                                        boolean bFormatsEnd = false;
636
                                        ArrayList formats = new ArrayList();
637
                                        while (!bFormatsEnd) {
638
                                                switch (formatsTag) {
639
                                                case KXmlParser.START_TAG:
640
                                                        if (parser.getName().compareTo(WebMapContextTags.FORMAT) == 0) {
641
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
642
                                                                String format = parser.nextText();
643
                                                                if (current!=null && current.equals("1"))
644
                                                                        layer.setFormat(format);
645
                                                                formats.add(format);
646
                                                        } else {
647
                                                                System.out.println("Unrecognized "+parser.getName());
648
                                                        }
649
                                                        break;
650
                                                case KXmlParser.END_TAG:
651
                                                        if (parser.getName().compareTo(WebMapContextTags.FORMAT_LIST) == 0)
652
                                                                bFormatsEnd = true;
653
                                                        break;
654
                                                case KXmlParser.TEXT:
655
                                                        if (parser.getName()!=null)
656
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
657
                                                        break;
658
                                                }
659
                                                formatsTag = parser.next();
660
                                        }
661
                                        if (layerFormats == null)
662
                                                layerFormats = new Hashtable();
663
                                        layerFormats.put(layer, formats.toArray(new String[0]));
664

    
665
                                } else if (parser.getName().compareTo(WebMapContextTags.STYLE_LIST) == 0) {
666
                                        int stylesTag = parser.nextTag();
667
                                        boolean bStylesEnd = false;
668
                                        ArrayList styles = new ArrayList();
669
                                        while (!bStylesEnd) {
670
                                                switch (stylesTag) {
671
                                                case KXmlParser.START_TAG:
672
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0) {
673
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
674
                                                                FMapWMSStyle style = parseStyle1_1_0(parser);
675
                                                                if (current!=null && current.equals("1")) {
676
                                                                        Vector v = new Vector();
677
                                                                        v.add(style.name);
678
                                                                        layer.setStyles(v);
679
                                                                }
680
                                                                styles.add(style);
681
                                                        } else {
682
                                                                System.out.println("Unrecognized "+parser.getName());
683
                                                        }
684
                                                        break;
685
                                                case KXmlParser.END_TAG:
686
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE_LIST) == 0)
687
                                                                bStylesEnd = true;
688
                                                        break;
689
                                                case KXmlParser.TEXT:
690
                                                        if (parser.getName()!=null)
691
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
692
                                                        break;
693
                                                }
694
                                                stylesTag = parser.next();
695
                                        }
696
                                        if (layerStyles == null)
697
                                                layerStyles = new Hashtable();
698

    
699
                                        layerStyles.put(layer, styles.toArray(new FMapWMSStyle[0]));
700
                                } else {
701
                                        System.out.println("Unrecognized "+parser.getName());
702
                                }
703
                                break;
704
                        case KXmlParser.END_TAG:
705
                                if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0)
706
                                        end = true;
707
                                break;
708
                        case KXmlParser.TEXT:
709
                                if (parser.getName()!=null)
710
                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
711
                                break;
712
                    }
713
                    tag = parser.next();
714
            }
715
            return layer;
716
        }
717

    
718
        private FMapWMSStyle parseStyle1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
719
                boolean end = false;
720
                String styleName = null;
721
                String styleAbstract = null;
722
                String styleTitle = null;
723
                int legendWidth = -1;
724
                int legendHeight = -1;
725
                String legendType = null;
726
                String legendHref = null;
727

    
728
            int tag = parser.next();
729
            while (!end) {
730
                    switch(tag) {
731
                        case KXmlParser.START_TAG:
732
                                if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
733
                                        styleName = parser.nextText();
734
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
735
                                        styleAbstract = parser.nextText();
736
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
737
                                        styleTitle = parser.nextText();
738
                                } else if (parser.getName().compareTo(WebMapContextTags.LEGEND_URL) == 0){
739
                                        legendWidth = Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH));
740
                                        legendHeight = Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT));
741
                                        parser.nextTag();
742
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0 ) {
743
                                                        legendType = parser.getAttributeValue("", WebMapContextTags.XLINK_TYPE);
744
                                                        legendHref = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
745
                                        }
746
                                } else {
747
                            System.out.println("Unrecognized "+parser.getName());
748
                                        }
749
                                break;
750
                         case KXmlParser.END_TAG:
751
                                if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0)
752
                                        end = true;
753
                                break;
754
                        case KXmlParser.TEXT:
755
                                if (parser.getName()!=null)
756
                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
757
                                break;
758
                    }
759
                    tag = parser.next();
760
            }
761
            WMSLayerNode n = new WMSLayerNode();
762
            FMapWMSStyle sty = n.new FMapWMSStyle();
763
            sty.name = styleName;
764
            sty.title = styleTitle;
765
            sty.styleAbstract = styleAbstract;
766
            sty.legendWidth = legendWidth;
767
            sty.legendHeight = legendHeight;
768
            sty.type = legendType;
769
            sty.href = legendHref;
770
            sty.parent = null;
771
            return sty;
772
        }
773

    
774
        /**
775
         * Creates the Web Map Context (WMC) XML according on the version 1.1.0. Since Web
776
         * WMC 1.0.0 is a subset of WMC 1.1.0 and this method does not produce tags for
777
         * unset values, it can be used to produce WMC 1.0.0, or even to produce
778
         * the deprecated (but still alive) WMC 0.1.4.
779
         * @param v
780
         * @return
781
         */
782
        private String createMapContext1_1_0(ProjectView v) {
783
                ArrayList layersToExport = getExportableLayers(v);
784

    
785
                XmlBuilder xml = new XmlBuilder();
786
                HashMap xmlAttrs = new HashMap();
787
                xml.setEncoding("ISO-8859-1"); // TODO make it customizable???
788
                xml.writeHeader();
789

    
790
                // <ViewContext>
791
                String viewContextTag;
792
                if (fileVersion.equals("0.1.4"))
793
                        viewContextTag = WebMapContextTags.VIEW_CONTEXT_0_1_4;
794
                else
795
                        viewContextTag = WebMapContextTags.VIEW_CONTEXT;
796

    
797
                xml.writeRaw("<!-- "+PluginServices.getText(this, "created_with")+" gvSIG "+Project.VERSION+" -->");
798

    
799
                xmlAttrs.put(WebMapContextTags.VERSION, fileVersion);
800
                xmlAttrs.put(WebMapContextTags.ID, id);
801
                xmlAttrs.put(WebMapContextTags.XMLNS, WebMapContextTags.XMLNS_VALUE);
802
                xmlAttrs.put(WebMapContextTags.XMLNS_XLINK, WebMapContextTags.XMLNS_XLINK_VALUE);
803
                xmlAttrs.put(WebMapContextTags.XMLNS_XSI, WebMapContextTags.XMLNS_XSI_VALUE);
804
                xmlAttrs.put(WebMapContextTags.XSI_SCHEMA_LOCATION, WebMapContextTags.XSI_SCHEMA_LOCATION_VALUE);
805
                xml.openTag(viewContextTag,  xmlAttrs);
806
                xmlAttrs.clear();
807

    
808
                        // <General>
809
                        xml.openTag(WebMapContextTags.GENERAL);
810

    
811
                                // <Window>
812
                                if (windowSize!=null) {
813
                                        xmlAttrs.put(WebMapContextTags.WIDTH, ((int) windowSize.getWidth())+"");
814
                                        xmlAttrs.put(WebMapContextTags.HEIGHT, ((int) windowSize.getHeight())+"");
815
                                        xml.writeTag(WebMapContextTags.WINDOW, xmlAttrs);
816
                                        xmlAttrs.clear();
817
                                }
818
                                // </Window>
819

    
820
                                // <BoundingBox>
821
                                xmlAttrs.put(WebMapContextTags.SRS, v.getProjection().getAbrev());
822
                                xmlAttrs.put(WebMapContextTags.X_MIN, bBox.getMinX()+"");
823
                                xmlAttrs.put(WebMapContextTags.Y_MIN, bBox.getMinY()+"");
824
                                xmlAttrs.put(WebMapContextTags.X_MAX, bBox.getMaxX()+"");
825
                                xmlAttrs.put(WebMapContextTags.Y_MAX, bBox.getMaxY()+"");
826
                                xml.writeTag(WebMapContextTags.BOUNDING_BOX, xmlAttrs);
827
                                xmlAttrs.clear();
828
                                // </BoundingBox>
829

    
830
                                // <Title>
831
                                xml.writeTag(WebMapContextTags.TITLE, title.trim());
832
                                // </Title>
833

    
834
                                // <Abstract>
835
                                if (_abstract != null)
836
                                        xml.writeTag(WebMapContextTags.ABSTRACT, _abstract.trim());
837
                                // </Abstract>
838

    
839
                                // <LogoURL>
840
                                if (logoURL != null)
841
                                        xml.writeTag(WebMapContextTags.LOGO_URL, logoURL.trim());
842
                                // </LogoURL>
843

    
844
                                // <DescriptionURL>
845
                                if (descriptionURL != null)
846
                                        xml.writeTag(WebMapContextTags.DESCRIPTION_URL, descriptionURL.trim());
847
                                // </DescriptionURL>
848

    
849
                                if (contactInfo) {
850

    
851
                                        // <ContactInformation>
852
                                        xml.openTag(WebMapContextTags.CONTACT_INFORMATION);
853
                                        if (contactPerson != null || contactOrganization != null) {
854

    
855
                                                // <ContactPersonPrimary>
856
                                                xml.openTag(WebMapContextTags.CONTACT_PERSON_PRIMARY);
857

    
858
                                                        // <ContactPerson>
859
                                                        if (contactPerson != null)
860
                                                                xml.writeTag(WebMapContextTags.CONTACT_PERSON, contactPerson.trim());
861
                                                        // </ContactPerson>
862

    
863
                                                        // <ContactOrganization>
864
                                                        if (contactOrganization != null)
865
                                                                xml.writeTag(WebMapContextTags.CONTACT_ORGANIZATION, contactOrganization.trim());
866
                                                        // </ContactOrganization>
867

    
868
                                                xml.closeTag();
869
                                                // </ContactPersonPrimary>
870
                                        }
871
                                        xml.closeTag();
872
                                        // </ContactInformation>
873

    
874
                                        // <ContactPosition>
875
                                        if (contactPosition != null)
876
                                                xml.writeTag(WebMapContextTags.CONTACT_POSITION, contactPosition.trim());
877
                                        // </ContactPosition>
878

    
879
                                        // <ContactAddress>
880
                                        if (address != null || city != null || stateOrProvince != null || postCode != null || country != null) {
881
                                                xml.openTag(WebMapContextTags.CONTACT_ADDRESS);
882

    
883
                                                        // <AddressType>
884
                                                        xml.writeTag(WebMapContextTags.ADDRESS_TYPE, "Postal");
885
                                                        // </AddressType>
886

    
887
                                                        // <Address>
888
                                                        if (address != null)
889
                                                                xml.writeTag(WebMapContextTags.ADDRESS, address.trim());
890
                                                        // </Address>
891

    
892
                                                        // <City>
893
                                                        if (city != null)
894
                                                                xml.writeTag(WebMapContextTags.CITY, city.trim());
895
                                                        // </City>
896

    
897
                                                        // <StateOrProvince>
898
                                                        if (stateOrProvince != null)
899
                                                                xml.writeTag(WebMapContextTags.STATE_OR_PROVINCE, stateOrProvince.trim());
900
                                                        // </StateOrProvince>
901

    
902
                                                        // <PostCode>
903
                                                        if (postCode != null)
904
                                                                xml.writeTag(WebMapContextTags.POSTCODE, postCode.trim());
905
                                                        // </PostCode>
906

    
907
                                                        // <Country>
908
                                                        if (country != null)
909
                                                                xml.writeTag(WebMapContextTags.COUNTRY, country.trim());
910
                                                        // </Country>
911
                                                xml.closeTag();
912
                                        }
913
                                        // </ContactAddress>
914

    
915
                                        // <ContactVoiceTelephone>
916
                                        if (telephone != null)
917
                                                xml.writeTag(WebMapContextTags.CONTACT_VOICE_TELEPHONE, telephone.trim());
918
                                        // </ContactVoiceTelephone>
919

    
920
                                        // <ContactFacsimileTelephone>
921
                                        if (fax != null)
922
                                                xml.writeTag(WebMapContextTags.CONTACT_FACSIMILE_TELEPHONE, fax.trim());
923
                                        // </ContactFacsimileTelephone>
924

    
925
                                        // <ContactElectronicMailAddress>
926
                                        if (email != null)
927
                                                xml.writeTag(WebMapContextTags.CONTACT_ELECTRONIC_MAIL_ADDRESS, email.trim());
928
                                        // </ContactElectronicMailAddress>
929
                                }
930
                                // <KeywordList>
931
                                xml.openTag(WebMapContextTags.KEYWORD_LIST);
932
                                if (keywordList != null) {
933
                                        for (int i = 0; i < keywordList.size(); i++) {
934
                                                xml.writeTag(WebMapContextTags.KEYWORD, ((String) keywordList.get(i)).trim());
935
                                        }
936
                                } else {
937
                                        xml.writeTag(WebMapContextTags.KEYWORD, "");
938
                                }
939
                                xml.closeTag();
940

    
941
                                // </KeywordList>
942
                        xml.closeTag();
943
                        // </General>
944

    
945
                        // <LayerList>
946
                        xml.openTag(WebMapContextTags.LAYER_LIST);
947
                        for (int i = 0; i < layersToExport.size(); i++) {
948
                                xml.writeRaw(((FLyrWMS) layersToExport.get(i)).toMapContext(fileVersion));
949
                        }
950
                        xml.closeTag();
951
                        // </LayerList>
952
                xml.closeTag();
953
                // </ViewContext>
954

    
955
                return xml.getXML();
956
        }
957

    
958
        /**
959
         * Exports the ProjectView passed as parameter to Web Map Context XML compliant
960
         * with the defined specifications for the version set in the fileVersion field.
961
         * @param ProjectView to be exported
962
         * @return String containing the XML
963
         */
964
        public String toXML(ProjectView v) {
965
                if (fileVersion.equals("1.1.0") ||
966
                                fileVersion.equals("1.0.0") ||
967
                                fileVersion.equals("0.1.4")) {
968
                        return createMapContext1_1_0(v);
969
                }
970
                return null;
971
        }
972

    
973

    
974
        public static ArrayList getExportableLayers(ProjectView v) {
975
                ArrayList list = new ArrayList();
976
                FLayers lyrs = v.getMapContext().getLayers();
977
                list.addAll(_getExportableLayers(lyrs));
978
                return list;
979
        }
980

    
981
        private static ArrayList _getExportableLayers(FLayer lyr) {
982
                ArrayList list = new ArrayList();
983
                if (checkType(lyr)) {
984
                        list.add(lyr);
985
                } else {
986
                        if (lyr instanceof FLayers) {
987
                                FLayers lyrs = (FLayers) lyr;
988
                                for (int i = 0; i < lyrs.getLayersCount(); i++) {
989
                                        list.addAll(_getExportableLayers(lyrs.getLayer(i)));
990
                                }
991
                        }
992
                }
993
                return list;
994
        }
995

    
996
        /**
997
         * Checks if the layer is supported by the WebMapContext
998
         * @param lyr
999
         * @return
1000
         */
1001
        private static boolean checkType(FLayer lyr) {
1002
                return supportedLayers.contains(lyr.getClass());
1003
        }
1004

    
1005
        /**
1006
         * Searches in the layer tree of the TOC for an ocurrence of any
1007
         * exportable layer and returns true if so, or false otherwise.
1008
         * @param layer
1009
         * @return
1010
         */
1011
        public static boolean containsExportableLayers(FLayer layer) {
1012
                if (checkType(layer))
1013
                        return true;
1014

    
1015
                if (layer instanceof FLayers) {
1016
                        FLayers layers = (FLayers) layer;
1017
                        for (int i = 0; i < layers.getLayersCount(); i++) {
1018
                                FLayer lyr = layers.getLayer(i);
1019
                                if (containsExportableLayers(lyr))
1020
                                        return true;
1021

    
1022
                        }
1023
                }
1024
                return false;
1025
        }
1026
}