Statistics
| Revision:

root / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / wms / WMSProtocolHandler.java @ 3405

History | View | Annotate | Download (11.2 KB)

1

    
2
package org.gvsig.remoteClient.wms;
3

    
4
import java.io.BufferedOutputStream;
5
import java.io.DataOutputStream;
6
import java.io.File;
7
import java.io.FileOutputStream;
8
import java.io.IOException;
9
import java.io.InputStream;
10
import java.io.OutputStream;
11
import java.net.ConnectException;
12
import java.net.URL;
13
import java.net.UnknownHostException;
14
import java.util.TreeMap;
15
import java.util.Vector;
16
import org.gvsig.remoteClient.utils.Utilities;
17

    
18
import com.devx.io.TempFileManager;
19

    
20

    
21
/**
22
 * <p> Abstract class that represents handlers to comunicate via WMS protocol.
23
 * </p>
24
 * 
25
 */
26
public abstract class WMSProtocolHandler {
27

    
28
        // procotol handler name
29
    protected String name;
30
    // protocol handler version
31
    protected String version;
32
    //host of the WMS to conenct
33
    protected String host;
34
    // port number of the comunication channel of the WMS to connect
35
    protected String port;    
36
    //WMS metadata
37
    protected ServiceInformation serviceInfo;
38
    public TreeMap layers;
39
    public Vector srs;
40
    
41

    
42
    // abstract methods to implement by the handlers that implement
43
    // the connection to a WMS with certain version.
44
    //    public abstract String getName();   
45
    //    public abstract String getVersion();
46
    
47
    /**
48
     * parses the data retrieved by the WMS in XML format. 
49
     * It will be mostly the WMS Capabilities, but the implementation
50
     * will be placed in the handler implementing certain version of the protocol.
51
     * 
52
     */
53
    public abstract void parse(File f);
54

    
55
    public String getName() {        
56
            return name;
57
    } 
58

    
59
    public String getVersion() {        
60
            return version;
61
    }    
62
    
63
    public ServiceInformation getServiceInformation() {        
64
        return serviceInfo;
65
    }  
66
    public String getHost ()
67
    {
68
            return host;
69
    }
70
    public void setHost(String _host)
71
    {
72
            host = _host;
73
    }
74
    public String getPort()
75
    {
76
            return port;
77
    }
78
    public void setPort(String _port)
79
    {
80
            port = _port;
81
    }
82

    
83
    /**
84
     * <p>Builds a GetMap request that is sent to the WMS
85
     * the response (image) will be redirect to the
86
     * WMS client</p>
87
     */
88
    
89
    public byte[] getMap(WMSStatus status)
90
    {        
91
            URL request = null;
92
                try
93
                {
94
                        //TODO:
95
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
96
                        request = new URL(buildMapRequest(status));
97
                    byte[] buffer = new byte[1024*256];
98
                    byte[] imageBytes = null;
99
                    InputStream is = request.openStream();
100
                    int readed = 0;
101
                    
102
                    for (int i = is.read(buffer); i>0; i = is.read(buffer)){
103
                            byte[] buffered = new byte[readed+i];
104
                            for (int j = 0; j < buffered.length; j++) {
105
                                    if (j<readed){
106
                                            buffered[j] = imageBytes[j];
107
                                    }
108
                                    else {
109
                                            buffered[j] = buffer[j-readed];
110
                                    }
111
                                }
112
                            imageBytes = (byte[]) buffered.clone();
113
                            readed += i;
114
                            
115
                    }
116
                        
117
                        return imageBytes;
118
                    
119
                }
120
                catch(Exception e)
121
                {
122
                        e.printStackTrace();
123
                }
124
                
125
                return null;
126
    } 
127

    
128
        /**
129
         * <p>Builds a GetCapabilities request that is sent to the WMS
130
         * the response will be parse to extract the data needed by the
131
         * WMS client</p>
132
         */
133
    public void getCapabilities()
134
    {                
135
            URL request = null;
136
                try
137
                {
138
                        request = new URL(buildCapabilitiesRequest());
139
                }
140
                catch(Exception e)
141
                {
142
                        e.printStackTrace();
143
                }
144
                
145
//                   File f = null;
146
//                   f = new File("tochangethis.txt");
147
//            
148
//            if (!f.exists())
149
//            {
150
//                    try
151
//                    {
152
//                            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
153
//                            byte[] buffer = new byte[1024*256];
154
//                            InputStream is = request.openStream();
155
//                            long readed = 0;
156
//                            for (int i = is.read(buffer); i>0; i = is.read(buffer)){
157
//                                    dos.write(buffer, 0, i);
158
//                                    readed += i;
159
//                            }
160
//                            dos.close();
161
//                    }
162
//                    catch(Exception e)
163
//                    {}
164
//            }
165
                try
166
                {
167
                File f = downloadFile(request,"wms_capabilities.xml");
168
            parse(f);
169
                }
170
                catch(Exception e)
171
                {
172
                        //TODO
173
                        e.printStackTrace();
174
                }
175
    }
176

    
177
/**
178
 * <p>It will send a GetFeatureInfo request to the WMS
179
 * Parsing the response and redirecting the info to the WMS client</p>
180
 */
181
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount)
182
    {
183
            URL request = null;
184
                try
185
                {
186
                        //TODO:
187
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
188
                        request = new URL(buildGetFeatureInfoRequest(status, x, y));
189
                }
190
                catch(Exception e)
191
                {
192
                        // TODO something about the exceptionsssss....!!!
193
                }
194
                
195
            try
196
            {            
197
                    System.out.println(request.toString());
198
                    File f = new File("featureInfo.xml");
199
                    DataOutputStream dos = new DataOutputStream(new FileOutputStream(f));
200
                    
201
                    OutputStream bos = null;
202

    
203
                    byte[] buffer = new byte[1024*256];
204
                    InputStream is = request.openStream();
205
                    //long readed = 0;
206
                    for (int i = is.read(buffer); i>0; i = is.read(buffer)){
207
                            dos.write(buffer, 0, i);
208
                            //readed += i;
209
                    }
210
                    dos.close();
211
                    
212
            return null;
213
            }
214
            catch(Exception e)
215
            {
216
                    //TODO
217
                    //Implement the correct logic to handle all the exceptions.
218
                    return null;
219
            }
220
    }
221

    
222
    /**
223
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
224
     */
225
    private String buildCapabilitiesRequest()
226
    {
227
                String req = new String();
228
                String host = getHost();
229
                if (!host.endsWith("?"))
230
                        req = req + getHost() + "?REQUEST=GetCapabilities&SERVICE=WMS&";
231
                else
232
                        req = req + getHost() + "REQUEST=GetCapabilities&SERVICE=WMS&";
233
                req = req + "VERSION=" + getVersion();
234
                req += ("&EXCEPTIONS=XML");
235
                return req;
236
    }
237

    
238
    /**
239
     * Builds the GetFeatureInfoRequest according to the OGC WMS Specifications
240
     */
241
    private String buildGetFeatureInfoRequest(WMSStatus status, int x, int y)
242
    {
243
                String req = new String();
244
                if (!host.endsWith("?"))
245
                        req = req + getHost() + "?REQUEST=GetFeatureInfo&SERVICE=WMS&";
246
                else
247
                        req = req + getHost() + "REQUEST=GetFeatureInfo&SERVICE=WMS&";
248
                req = req + "QUERY_LAYERS="+Utilities.Vector2CS(status.getLayerNames()); 
249
                req = req + "&VERSION=" + getVersion() + "&";
250
                req = req + getPartialQuery(status);
251
                req = req + "&x="+x + "&y="+y;
252
       if (status.getExceptionFormat() != null) {
253
            req += ("&EXCEPTIONS=" + status.getExceptionFormat());
254
        } else {
255
            req += ("&EXCEPTIONS=XML");
256
        }
257
                return req;
258
    }    
259
    
260
    /**
261
     * Builds the GetMapRequest according to the OGC WMS Specifications
262
     */
263
    private String buildMapRequest(WMSStatus status)
264
    {
265
                String req = new String();
266
                if (!host.endsWith("?"))
267
                        req = req + getHost() + "?REQUEST=GetMap&SERVICE=WMS&";
268
                else
269
                        req = req + getHost() + "REQUEST=GetMap&SERVICE=WMS&";
270
                req = req + "VERSION=" + getVersion() + "&";
271
                req = req + getPartialQuery(status);
272
       if (status.getExceptionFormat() != null) {
273
            req += ("&EXCEPTIONS=" + status.getExceptionFormat());
274
        } else {
275
            req += ("&EXCEPTIONS=XML");
276
        }
277
                return req;
278
    }
279

    
280
    /**
281
     * Gets the part of the OGC request that share GetMap and GetFeatureInfo
282
     * @return String request
283
     */
284
    public String getPartialQuery(WMSStatus status)
285
    {            
286
        String req = "LAYERS=" + Utilities.Vector2CS(status.getLayerNames()) + "&STYLES=" +
287
        Utilities.Vector2CS(status.getStyles()) + "&SRS=" + status.getSrs() +
288
            "&BBOX=" + status.getExtent().getMinX()+ "," +
289
                                    status.getExtent().getMinY()+ "," +
290
                                    status.getExtent().getMaxX()+ "," +
291
                                    status.getExtent().getMaxY() +
292
            "&WIDTH=" + status.getWidth() +
293
            "&HEIGHT=" + status.getHeight() + "&FORMAT=" + status.getFormat();
294

    
295
//        if (status.getTransparency()) {
296
//            req += "&TRANSPARENT=TRUE";
297
//        }
298
//
299
//        if (status.getBGColor() != null) {
300
//            req += ("&COLOR=" + status.getBGColor());
301
//        }
302
//
303
//        if (time != null) {
304
//            req += ("&TIME=" + time);
305
//        }
306
//
307
//        if (elevation != -1) {
308
//            req += ("&ELEVATION=" + elevation);
309
//        }
310

    
311
        return req.replaceAll(" ", "%20");
312
    }
313

    
314
    
315
    
316
    public void close() {        
317
        // your code here
318
    } 
319
    
320
    /**
321
     * Inner class that represents the description of the WMS metadata.
322
     * The first part of the capabilities will return the service information
323
     * from the WMS, this class will hold this information. 
324
     * 
325
     */
326
    public class ServiceInformation {
327

    
328
        public String online_resource;
329
        public String version;
330
        public String name;
331
        public String scope;
332
        public String title;
333
        public String abstr;
334
        public String keywords;
335
        public String fees;
336
        public String operationsInfo;
337
        public String personname;
338
        public String organization;
339
        public String function;
340
        public String addresstype;
341
        public String address;
342
        public String place;
343
        public String province;
344
        public String postcode;
345
        public String country;
346
        public String phone;
347
        public String fax;
348
        public String email;
349
        public Vector formats;
350
        
351
        public ServiceInformation()
352
        {
353
                online_resource = new String();
354
            version = new String();
355
            name = new String();
356
            scope = new String();
357
            title = new String();
358
            abstr = new String();
359
            keywords = new String();
360
            fees = new String();
361
            operationsInfo = new String();
362
            personname = new String();
363
            organization = new String();
364
            function = new String();
365
            addresstype = new String();
366
            address = new String();
367
            place = new String();
368
            province = new String();
369
            postcode = new String();
370
            country = new String();
371
            phone = new String();
372
            fax = new String();
373
            email = new String();
374
            formats = new Vector();               
375
        }
376
     }   
377
    
378
    /**
379
     * Downloads an URL into a temporary file that is removed the next time the 
380
     * tempFileManager class is called, which means the next time gvSIG is launched.
381
     * 
382
     * @param url
383
     * @param name
384
     * @return
385
     * @throws IOException
386
     * @throws ServerErrorResponseException
387
     * @throws ConnectException
388
     * @throws UnknownHostException
389
     */
390
    private File downloadFile(URL url, String name) throws IOException,ConnectException, UnknownHostException{
391
            File f = null;
392

    
393
            try{
394
                    f = TempFileManager.createTempFile(name, "tmp");
395
                    System.out.println("downloading '"+url.toString()+"' to: "+f.getAbsolutePath());
396
                         
397
                    f.deleteOnExit();
398
                    
399
            } catch (IOException io) {
400
                    io.printStackTrace();
401
            }
402
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
403
            byte[] buffer = new byte[1024*256];
404
            InputStream is = url.openStream();
405
            long readed = 0;
406
            for (int i = is.read(buffer); i>0; i = is.read(buffer)){
407
                    dos.write(buffer, 0, i);
408
                    readed += i;
409
            }
410
            dos.close();
411
            /*if (!isNotAnException(f))
412
                    // SI que es una excepci?n
413
                    throw new ServerErrorResponseException();*/
414
            return f;
415
        }
416

    
417
 }