Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libRemoteServices / src / org / gvsig / remoteclient / wmts / WMTSProtocolHandler.java @ 34393

History | View | Annotate | Download (10.1 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
package org.gvsig.remoteclient.wmts;
23

    
24
import java.io.ByteArrayInputStream;
25
import java.io.File;
26
import java.io.FileReader;
27
import java.io.IOException;
28
import java.net.URL;
29
import java.util.ArrayList;
30
import java.util.StringTokenizer;
31

    
32
import org.gvsig.compat.net.ICancellable;
33
import org.gvsig.remoteclient.exceptions.ServerErrorException;
34
import org.gvsig.remoteclient.ogc.OGCProtocolHandler;
35
import org.gvsig.remoteclient.ogc.OGCServiceInformation;
36
import org.gvsig.remoteclient.utils.ExceptionTags;
37
import org.gvsig.remoteclient.utils.Utilities;
38
import org.gvsig.remoteclient.wmts.exception.WMTSException;
39
import org.gvsig.remoteclient.wmts.request.WMTSGetCapabilitiesRequest;
40
import org.gvsig.remoteclient.wmts.request.WMTSGetFeatureInfoRequest;
41
import org.gvsig.remoteclient.wmts.request.WMTSGetTileRequest;
42
import org.kxml2.io.KXmlParser;
43
import org.xmlpull.v1.XmlPullParserException;
44

    
45
/**
46
 * <p> Abstract class that represents handlers to comunicate via WMS protocol.</p>
47
 * 
48
 * @author Nacho Brodin (nachobrodin@gmail.com)
49
 */
50
public abstract class WMTSProtocolHandler extends OGCProtocolHandler {
51
        /**
52
         * Encoding used to parse different xml documents.
53
         */
54
        protected String                 encoding    = "UTF-8";
55
    protected WMTSServiceInformation serviceInfo = null;
56
    
57
    protected abstract WMTSGetFeatureInfoRequest createGetFeatureInfoRequest(WMTSStatus status, int x, int y);
58

    
59
    protected abstract WMTSGetTileRequest createGetTileRequest(WMTSStatus status);
60
    
61
    protected abstract WMTSGetCapabilitiesRequest createGetCapabilitiesRequest();
62
    
63
    /**
64
     * Sets the status object
65
     * @param status
66
     */
67
    protected abstract void setStatus(WMTSServerDescription status);
68
    
69
    public File getTile(WMTSStatus status, ICancellable cancel) throws ServerErrorException, WMTSException {
70
            try {
71
                        WMTSGetTileRequest request = createGetTileRequest(status);
72
                        File f = request.sendRequest(cancel);
73
                        
74
                        if (f== null)
75
                            return null;
76
            if (Utilities.isTextFile(f)) {
77
                byte[] data = fileToBytes(f);
78

    
79
                            WMTSException wmsEx = null;
80

    
81
                    String exceptionMessage = parseException(data);
82
                if (exceptionMessage == null) {
83
                         String error = new String(data);
84
                        int pos = error.indexOf("<?xml");
85
                        if (pos!= -1) {
86
                                String xml = error.substring(pos,error.length());
87
                                exceptionMessage = parseException(xml.getBytes());
88
                        }
89
                    if (exceptionMessage == null)
90
                            exceptionMessage = new String(data);
91

    
92
                }
93
                     wmsEx = new WMTSException(exceptionMessage);
94

    
95
                    // Since it is an error file, It must be deleted from the cache
96
                    downloader.removeURL(request);
97
                throw wmsEx;
98
            }
99
                        return f;
100
                }
101
                catch(IOException e) {
102
                        e.printStackTrace();
103
            throw new ServerErrorException();
104
                }
105
    }
106
    
107
        /**
108
     * <p>It will send a GetFeatureInfo request to the WMTS
109
     * Parsing the response and redirecting the info to the WMTS client</p>
110
     * TODO: return a stored file instead a String.
111
     */
112
    public String getFeatureInfo(WMTSStatus status, int x, int y, ICancellable cancel) {
113
            StringBuffer output = new StringBuffer();
114
            String outputFormat = new String();
115
            String ServiceException = "ServiceExceptionReport";
116
            StringBuffer sb = new StringBuffer();
117
            sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
118
                try {
119
                        WMTSGetFeatureInfoRequest request = createGetFeatureInfoRequest(status, x, y);
120
                        URL url = request.getURL();
121
                    outputFormat = url.openConnection().getContentType();
122
                    File f = request.sendRequest(cancel);
123
                        if (f == null) {
124
                                return "";
125
                        }
126

    
127
                        FileReader fReader = new FileReader(f);
128
                        char[] buffer = new char[1024*256];
129
                        for (int i = fReader.read(buffer); i > 0; i = fReader.read(buffer)) {
130
                            String str = new String(buffer,0,i);
131
                            output.append(str);
132
                    }
133
                    if ( (outputFormat == null) || (outputFormat.indexOf("xml") != -1)
134
                                    ||output.toString().toLowerCase().startsWith("<?xml")
135
                                    ||(outputFormat.indexOf("gml") != -1)) {
136
                            KXmlParser kxmlParser = null;
137
                            kxmlParser = new KXmlParser();
138
                            //kxmlParser.setInput(new StringReader(output.toString()));
139
                            kxmlParser.setInput(new FileReader(f));
140

    
141
                            kxmlParser.nextTag();
142
                            if (kxmlParser.getName().compareTo(ServiceException) == 0) {
143
                                    sb.append("<INFO>").append(parseException( output.toString().getBytes())).append("</INFO>");
144
                                    return sb.toString();
145
                                } else if (kxmlParser.getName().compareToIgnoreCase("ERROR") == 0) {
146
                                        return output.toString();
147
                                } else {
148
                                        return output.toString();
149
                                }
150
                    } else {                  
151
                             return output.toString();
152
                    }
153
                } catch(XmlPullParserException parserEx) {
154
                    if (output.toString().toLowerCase().indexOf("xml") != -1) {
155
                            return output.toString().trim();
156
                    } else {
157
                               sb.append("<INFO>").append("Info format not supported").append("</INFO>");
158
                        return sb.toString();
159
                    }
160
            } catch(Exception e) {
161
                    e.printStackTrace();
162
                    sb.append("<INFO>").append("Info format not supported").append("</INFO>");
163
                    return sb.toString();
164
            }
165
    }
166

    
167
    /**
168
         * <p>Builds a GetCapabilities request that is sent to the WMS
169
         * the response will be parse to extract the data needed by the
170
         * WMS client</p>
171
         * @param override, if true the previous downloaded data will be overridden
172
         */
173
    public void getCapabilities(WMTSServerDescription status, boolean override, ICancellable cancel) {
174
            try {
175
                    setStatus(status);
176
                        WMTSGetCapabilitiesRequest request = createGetCapabilitiesRequest();
177
                        File f = request.sendRequest(cancel);                        
178
        
179
                        if (f == null)
180
                                return;
181
                        parseCapabilities(f);
182
            } catch(Exception e) {
183
                        e.printStackTrace();
184
                }
185
    }
186
    
187
    
188
    /**
189
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
190
     * without a VERSION, to get the highest version than a WMS supports.
191
     */
192
    public static String buildCapabilitiesSuitableVersionRequest(String _host, String _version) {
193
                int index = _host.indexOf('?');
194
                
195
                if (index > -1) {
196
                        String host = _host.substring(0, index + 1);
197
                        String query = _host.substring(index + 1, _host.length());
198
                        
199
                        StringTokenizer tokens = new StringTokenizer(query, "&");
200
                        String newQuery = "", token;
201

    
202
                        // If there is a field or a value with spaces, (and then it's on different tokens) -> unify them
203
                        while (tokens.hasMoreTokens()) {
204
                                token = tokens.nextToken().trim();
205

    
206
                                if (token.toUpperCase().compareTo("REQUEST=GETCAPABILITIES") == 0)
207
                                        continue;
208

    
209
                                if (token.toUpperCase().compareTo("SERVICE=WMTS") == 0)
210
                                        continue;
211

    
212
                                if ((_version != null) && (_version.length() > 0)) {
213
                                    if (token.toUpperCase().compareTo("VERSION=" + _version) == 0)
214
                                            continue;
215
                                }
216

    
217
                                if (token.toUpperCase().compareTo("EXCEPTIONS=XML") == 0)
218
                                        continue;
219

    
220
                                newQuery += token + "&";
221
                        }
222

    
223
                _host = host + newQuery;
224
                }
225
                else {
226
                        _host += "?";
227
                }
228

    
229
            if ((_version != null) && (_version.compareTo("") != 0))
230
                    _host += "REQUEST=GetCapabilities&SERVICE=WMTS&VERSION=" + _version;
231
            else
232
                    _host += "REQUEST=GetCapabilities&SERVICE=WMTS";
233

    
234
            return _host;
235
    }
236
    
237
   /*
238
    * (non-Javadoc)
239
    * @see org.gvsig.remoteclient.ogc.OGCProtocolHandler#getServiceInformation()
240
    */
241
    public OGCServiceInformation getServiceInformation() {
242
        return serviceInfo;
243
    }
244
    
245
        protected String parseException(byte[] data) {
246
        ArrayList errors = new ArrayList();
247
        KXmlParser kxmlParser = new KXmlParser();
248
        try
249
        {
250
            kxmlParser.setInput(new ByteArrayInputStream(data), encoding);
251
            kxmlParser.nextTag();
252
            int tag;
253
            if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
254
            {
255
                kxmlParser.require(KXmlParser.START_TAG, null, ExceptionTags.EXCEPTION_ROOT);
256
                tag = kxmlParser.nextTag();
257
                 while(tag != KXmlParser.END_DOCUMENT)
258
                 {
259
                     switch(tag)
260
                     {
261
                        case KXmlParser.START_TAG:
262
                            if (kxmlParser.getName().compareTo(ExceptionTags.SERVICE_EXCEPTION)==0){
263
                                String errorCode = kxmlParser.getAttributeValue("", ExceptionTags.CODE);
264
                                errorCode = (errorCode != null) ? "["+errorCode+"] " : "";
265
                                String errorMessage = kxmlParser.nextText();
266
                                errors.add(errorCode+errorMessage);
267
                            }
268
                            break;
269
                        case KXmlParser.END_TAG:
270
                            break;
271

    
272
                     }
273
                     tag = kxmlParser.nextTag();
274
                 }
275
                 //kxmlParser.require(KXmlParser.END_DOCUMENT, null, null);
276
            }
277
        }
278
        catch(XmlPullParserException parser_ex){
279
            parser_ex.printStackTrace();
280
        }
281
        catch (IOException ioe) {
282
            ioe.printStackTrace();
283
        }
284
        String message = errors.size()>0? "" : null;
285
        for (int i = 0; i < errors.size(); i++) {
286
            message += (String) errors.get(i)+"\n";
287
        }
288
        return message;
289
    }
290
    
291
 }