Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2021 / libraries / libRemoteServices / src / org / gvsig / remoteclient / wcs / WCSProtocolHandler.java @ 34101

History | View | Annotate | Download (10.7 KB)

1 3483 jaume
/* 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 29649 jpiera
package org.gvsig.remoteclient.wcs;
42 3483 jaume
43 4924 jaume
import java.io.ByteArrayInputStream;
44 3483 jaume
import java.io.File;
45 4493 jaume
import java.io.IOException;
46 17849 jmvivo
import java.net.MalformedURLException;
47 3483 jaume
import java.net.URL;
48 4427 jaume
import java.util.ArrayList;
49
import java.util.Hashtable;
50 17849 jmvivo
import java.util.StringTokenizer;
51 3483 jaume
52 33738 jpiera
import org.gvsig.compat.CompatLocator;
53
import org.gvsig.compat.lang.StringUtils;
54
import org.gvsig.compat.net.ICancellable;
55 29649 jpiera
import org.gvsig.remoteclient.exceptions.ServerErrorException;
56
import org.gvsig.remoteclient.exceptions.WCSException;
57
import org.gvsig.remoteclient.ogc.OGCProtocolHandler;
58 31834 jpiera
import org.gvsig.remoteclient.ogc.OGCServiceInformation;
59 29649 jpiera
import org.gvsig.remoteclient.utils.ExceptionTags;
60
import org.gvsig.remoteclient.utils.Utilities;
61
import org.gvsig.remoteclient.wcs.request.WCSDescribeCoverageRequest;
62
import org.gvsig.remoteclient.wcs.request.WCSGetCoverageRequest;
63 33983 nbrodin
import org.kxml2.io.KXmlParser;
64
import org.xmlpull.v1.XmlPullParserException;
65 3483 jaume
/**
66 7010 jaume
 *
67 3483 jaume
 * @author jaume
68
 *
69
 */
70 17849 jmvivo
public abstract class WCSProtocolHandler extends OGCProtocolHandler {
71 4500 jaume
        /**
72
         * Encoding used to parse different xml documents.
73
         */
74
        protected String encoding = "UTF-8";
75 4427 jaume
        protected Hashtable layerPool = new Hashtable();
76 7010 jaume
77 4924 jaume
        /**
78 3483 jaume
     * WCS metadata
79
     */
80 31834 jpiera
    protected WCSServiceInformation serviceInfo = new WCSServiceInformation();
81 33738 jpiera
82
    private static final StringUtils stringUtils = CompatLocator.getStringUtils();
83 7010 jaume
84 17849 jmvivo
        /*
85
         * (non-Javadoc)
86
         * @see org.gvsig.remoteClient.OGCProtocolHandler#setHost(java.lang.String)
87
         */
88
        public void setHost(String host) {
89
                try {
90
                        // Validates the URL if doesn't produces an exception
91
                        new URL(host);
92
93
                        int index = host.indexOf("?");
94
95
                        if (index == -1)
96
                                super.setHost(host);
97
                        else
98
                                super.setHost(host.substring(0, index));
99
                }
100
                catch (MalformedURLException m) {
101
                        // Bad URL -> hold it
102
                        super.setHost(host);
103
                }
104
        }
105
106
        /**
107 4924 jaume
     * <p>
108
     * Builds a GetCapabilities request that is sent to the WCS
109 3483 jaume
     * the response will be parse to extract the data needed by the
110 4924 jaume
     * WCS client.
111
     * </p>
112 9003 jaume
     * @param override, if true the cache is ignored
113 3483 jaume
     */
114 9003 jaume
    public void getCapabilities(WCSStatus status, boolean override, ICancellable cancel) {
115 3483 jaume
           URL request = null;
116 4427 jaume
            try {
117
                request = new URL(buildCapabilitiesRequest(status));
118 3483 jaume
            }
119 4427 jaume
            catch(Exception e) {
120 3483 jaume
                e.printStackTrace();
121
            }
122 4427 jaume
            try {
123 9003 jaume
                    if (override)
124 33738 jpiera
                        downloader.removeURL(request);
125
                    File f =  downloader.downloadFile(request,"wcs_capabilities.xml", cancel);
126 5409 jaume
                    if (f!=null)
127
                            parseCapabilities(f);
128 4427 jaume
            } catch(Exception e) {
129
                    e.printStackTrace();
130 3483 jaume
            }
131
    }
132 7010 jaume
133 3483 jaume
    /**
134 4924 jaume
     * Builds a complete URL-string that can be used to send a GetCapabilities request.
135
     * @return String
136 3483 jaume
     */
137 4427 jaume
    private String buildCapabilitiesRequest(WCSStatus status) {
138
            StringBuffer req = new StringBuffer();
139
                String symbol = null;
140 7010 jaume
141 4427 jaume
                String onlineResource;
142
                if (status == null || status.getOnlineResource() == null)
143
                        onlineResource = getHost();
144 7010 jaume
                else
145 4427 jaume
                        onlineResource = status.getOnlineResource();
146
                symbol = getSymbol(onlineResource);
147 7010 jaume
148 4427 jaume
                req.append(onlineResource).append(symbol).append("REQUEST=GetCapabilities&SERVICE=WCS&");
149
                req.append("VERSION=").append(getVersion()).append("&EXCEPTIONS=XML");
150
                return req.toString();
151 3483 jaume
    }
152 4427 jaume
153 7010 jaume
154
155 3483 jaume
    /**
156
     * parses the data retrieved by the DescribeCoverage XML document
157
     */
158 4222 jaume
    public abstract boolean parseDescribeCoverage(File f);
159 7010 jaume
160 4924 jaume
    /**
161
     * Send a DescribeCoverage request using the settings passed in the status argument.
162
     * If status is null, then default settings are used.
163 9003 jaume
     * @param override
164 4924 jaume
     * @return String
165
     */
166 9003 jaume
    public void describeCoverage(WCSStatus status, boolean override, ICancellable cancel) {
167 27881 jpiera
       try {
168
               WCSDescribeCoverageRequest request = createDescribeCoverageRequest(status);
169 33983 nbrodin
           File f = request.sendRequest(cancel);
170 5409 jaume
                if (f!=null)
171
                        parseDescribeCoverage(f);
172 4427 jaume
        } catch(Exception e) {
173
                e.printStackTrace();
174
        }
175 3483 jaume
    }
176 7010 jaume
177 4924 jaume
    /**
178
     * Send a GetCoverage request using the settings passed in the status.
179
     * @return String
180
     */
181 5409 jaume
    public File getCoverage(WCSStatus status, ICancellable cancel) throws ServerErrorException, WCSException {
182 27881 jpiera
            try
183 4493 jaume
                {
184
                        //TODO:
185
                        //pass this buildXXXRequest to the WCSProtocolHandlerXXX: The request can depend on the WCS version.
186 27881 jpiera
                        WCSGetCoverageRequest request = createGetCoverageRequest(status);
187 33983 nbrodin
            File f = request.sendRequest(cancel);
188 7010 jaume
189 5409 jaume
            if (f!=null && Utilities.isTextFile(f)) {
190 33738 jpiera
                byte[] data = fileToBytes(f);
191 7010 jaume
192 4493 jaume
                            WCSException wcsEx = null;
193 7010 jaume
194 4493 jaume
                    String exceptionMessage = parseException(data);
195
                if (exceptionMessage==null)
196
                {
197
                         String error = new String(data);
198
                        int pos = error.indexOf("<?xml");
199
                        if (pos!= -1)
200
                        {
201
                                String xml = error.substring(pos,error.length());
202
                                exceptionMessage = parseException(xml.getBytes());
203 7010 jaume
                        }
204 4493 jaume
                    if (exceptionMessage == null)
205
                            exceptionMessage = new String(data);
206 7010 jaume
207 4493 jaume
                }
208
                     wcsEx = new WCSException(exceptionMessage);
209
                    wcsEx.setWCSMessage(new String(data));
210 7010 jaume
211 4493 jaume
                    // Since it is an error file, It must be deleted from the cache
212 33738 jpiera
                    downloader.removeURL(request);
213 4493 jaume
                throw wcsEx;
214
            }
215 7010 jaume
                        return f;
216 4493 jaume
                }
217
                catch(IOException e)
218
                {
219
                        e.printStackTrace();
220
            throw new ServerErrorException();
221
                }
222 7010 jaume
    }
223
224
225 4924 jaume
    /**
226
     * Parses the WCS Exception document.
227
     * @param bytes, byte[]
228
     * @return
229
     */
230
    private String parseException(byte[] data) {
231
            // TODO: a?? est? fusilat del WMS, comprovar que funciona.
232
            ArrayList errors = new ArrayList();
233
        KXmlParser kxmlParser = new KXmlParser();
234
        try
235
        {
236 7010 jaume
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);
237 4924 jaume
            kxmlParser.nextTag();
238
            int tag;
239 7010 jaume
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
240
            {
241
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);
242 4924 jaume
                tag = kxmlParser.nextTag();
243
                 while(tag != KXmlParser.END_DOCUMENT)
244
                 {
245
                     switch(tag)
246
                     {
247
                        case KXmlParser.START_TAG:
248
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
249
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
250
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
251
                                String errorMessage = kxmlParser.nextText();
252
                                errors.add(errorCode+errorMessage);
253
                            }
254
                            break;
255 7010 jaume
                        case KXmlParser.END_TAG:
256 4924 jaume
                            break;
257 7010 jaume
258 4924 jaume
                     }
259
                     tag = kxmlParser.nextTag();
260
                 }
261
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
262
            }
263
        }
264 7010 jaume
        catch(XmlPullParserException parser_ex){
265 4924 jaume
            parser_ex.printStackTrace();
266
        }
267 7010 jaume
        catch (IOException ioe) {
268
            ioe.printStackTrace();
269 4924 jaume
        }
270
        String message = errors.size()>0? "" : null;
271
        for (int i = 0; i < errors.size(); i++) {
272
            message += (String) errors.get(i)+"\n";
273
        }
274
        return message;
275 27881 jpiera
        }
276 4493 jaume
277 4293 jaume
    /**
278 4427 jaume
     * Builds the GetCapabilitiesRequest according to the OGC WCS Specifications
279
     * without a VERSION, to get the highest version than a WCS supports.
280 4293 jaume
     */
281
    public static String buildCapabilitiesSuitableVersionRequest(String _host, String _version) {
282 17849 jmvivo
                int index = _host.indexOf('?');
283
284
                if (index > -1) {
285
                        String host = _host.substring(0, index + 1);
286
                        String query = _host.substring(index + 1, _host.length());
287
288
                        StringTokenizer tokens = new StringTokenizer(query, "&");
289
                        String newQuery = "", token;
290
291
                        // If there is a field or a value with spaces, (and then it's on different tokens) -> unify them
292
                        while (tokens.hasMoreTokens()) {
293
                                token = tokens.nextToken().trim();
294
295
                                if (token.toUpperCase().compareTo("REQUEST=GETCAPABILITIES") == 0)
296
                                        continue;
297
298
                                if (token.toUpperCase().compareTo("SERVICE=WCS") == 0)
299
                                        continue;
300
301
                                if ((_version != null) && (_version.length() > 0)) {
302
                                    if (token.toUpperCase().compareTo("VERSION=" + _version) == 0)
303
                                            continue;
304
                                }
305
306
                                if (token.toUpperCase().compareTo("EXCEPTIONS=XML") == 0)
307
                                        continue;
308
309
                                newQuery += token + "&";
310
                        }
311
312
                _host = host + newQuery;
313
                }
314
                else {
315
                        _host += "?";
316
                }
317
318
            if ((_version != null) && (_version.compareTo("") != 0))
319
                    _host += "REQUEST=GetCapabilities&SERVICE=WCS&VERSION=" + _version + "&EXCEPTIONS=XML";
320
            else
321
                    _host += "REQUEST=GetCapabilities&SERVICE=WCS&EXCEPTIONS=XML";
322
323 33738 jpiera
            return stringUtils.replaceAll(_host, " ", "%20");
324 4293 jaume
    }
325 7010 jaume
326 4931 jaume
        public ArrayList getFormats() {
327
                return new ArrayList(serviceInfo.formats);
328 31834 jpiera
        }
329 4931 jaume
330 4427 jaume
        public Hashtable getLayers() {
331
                return layerPool;
332 7010 jaume
        }
333 27881 jpiera
334
        public abstract WCSDescribeCoverageRequest createDescribeCoverageRequest(WCSStatus status);
335
336
        public abstract WCSGetCoverageRequest createGetCoverageRequest(WCSStatus status);
337 31834 jpiera
338
        /* (non-Javadoc)
339
         * @see org.gvsig.remoteclient.ogc.OGCProtocolHandler#getServiceInformation()
340 33738 jpiera
         */
341 31834 jpiera
        public OGCServiceInformation getServiceInformation() {
342
                return serviceInfo;
343
        }
344 27881 jpiera
345 3483 jaume
}