Source Code Cross Referenced for WFSDataStore.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » wfs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.data.wfs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *    GeoTools - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2004-2006, Geotools Project Managment Committee (PMC)
0005:         *
0006:         *    This library is free software; you can redistribute it and/or
0007:         *    modify it under the terms of the GNU Lesser General Public
0008:         *    License as published by the Free Software Foundation; either
0009:         *    version 2.1 of the License, or (at your option) any later version.
0010:         *
0011:         *    This library is distributed in the hope that it will be useful,
0012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         *    Lesser General Public License for more details.
0015:         */
0016:        package org.geotools.data.wfs;
0017:
0018:        import java.io.BufferedInputStream;
0019:        import java.io.IOException;
0020:        import java.io.InputStream;
0021:        import java.io.OutputStream;
0022:        import java.io.OutputStreamWriter;
0023:        import java.io.StringWriter;
0024:        import java.io.UnsupportedEncodingException;
0025:        import java.io.Writer;
0026:        import java.net.Authenticator;
0027:        import java.net.HttpURLConnection;
0028:        import java.net.MalformedURLException;
0029:        import java.net.PasswordAuthentication;
0030:        import java.net.URI;
0031:        import java.net.URISyntaxException;
0032:        import java.net.URL;
0033:        import java.net.URLEncoder;
0034:        import java.util.Arrays;
0035:        import java.util.HashMap;
0036:        import java.util.Iterator;
0037:        import java.util.List;
0038:        import java.util.Map;
0039:        import java.util.logging.Level;
0040:        import java.util.logging.Logger;
0041:        import java.util.zip.GZIPInputStream;
0042:
0043:        import javax.naming.OperationNotSupportedException;
0044:
0045:        import org.geotools.data.AbstractDataStore;
0046:        import org.geotools.data.DataSourceException;
0047:        import org.geotools.data.DataUtilities;
0048:        import org.geotools.data.DefaultQuery;
0049:        import org.geotools.data.EmptyFeatureReader;
0050:        import org.geotools.data.FeatureReader;
0051:        import org.geotools.data.FeatureSource;
0052:        import org.geotools.data.FilteringFeatureReader;
0053:        import org.geotools.data.Query;
0054:        import org.geotools.data.ReTypeFeatureReader;
0055:        import org.geotools.data.Transaction;
0056:        import org.geotools.data.crs.ForceCoordinateSystemFeatureReader;
0057:        import org.geotools.data.ows.FeatureSetDescription;
0058:        import org.geotools.data.ows.WFSCapabilities;
0059:        import org.geotools.feature.AttributeType;
0060:        import org.geotools.feature.AttributeTypeFactory;
0061:        import org.geotools.feature.FeatureType;
0062:        import org.geotools.feature.FeatureTypeBuilder;
0063:        import org.geotools.feature.GeometryAttributeType;
0064:        import org.geotools.feature.SchemaException;
0065:        import org.geotools.filter.ExpressionType;
0066:        import org.geotools.filter.FidFilter;
0067:        import org.opengis.filter.Filter;
0068:        import org.geotools.filter.FilterType;
0069:        import org.geotools.filter.Filters;
0070:        import org.geotools.filter.GeometryFilter;
0071:        import org.geotools.filter.LiteralExpression;
0072:        import org.geotools.filter.visitor.PostPreProcessFilterSplittingVisitor;
0073:        import org.geotools.filter.visitor.PostPreProcessFilterSplittingVisitor.WFSBBoxFilterVisitor;
0074:        import org.geotools.geometry.jts.JTS;
0075:        import org.geotools.geometry.jts.ReferencedEnvelope;
0076:        import org.geotools.referencing.CRS;
0077:        import org.geotools.referencing.crs.DefaultGeographicCRS;
0078:        import org.geotools.util.logging.Logging;
0079:        import org.geotools.xml.DocumentFactory;
0080:        import org.geotools.xml.DocumentWriter;
0081:        import org.geotools.xml.SchemaFactory;
0082:        import org.geotools.xml.filter.FilterSchema;
0083:        import org.geotools.xml.gml.GMLComplexTypes;
0084:        import org.geotools.xml.gml.WFSFeatureTypeTransformer;
0085:        import org.geotools.xml.schema.Element;
0086:        import org.geotools.xml.schema.Schema;
0087:        import org.geotools.xml.wfs.WFSSchema;
0088:        import org.opengis.referencing.FactoryException;
0089:        import org.opengis.referencing.NoSuchAuthorityCodeException;
0090:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0091:        import org.opengis.referencing.operation.MathTransform;
0092:        import org.opengis.referencing.operation.TransformException;
0093:        import org.opengis.geometry.MismatchedDimensionException;
0094:        import org.xml.sax.SAXException;
0095:
0096:        import com.vividsolutions.jts.geom.Envelope;
0097:        import com.vividsolutions.jts.geom.Geometry;
0098:
0099:        /**
0100:         * <p>
0101:         * DOCUMENT ME!
0102:         * </p>
0103:         *
0104:         * @author dzwiers
0105:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/wfs/src/main/java/org/geotools/data/wfs/WFSDataStore.java $
0106:         */
0107:        public class WFSDataStore extends AbstractDataStore {
0108:
0109:            protected WFSCapabilities capabilities = null;
0110:
0111:            protected static final int AUTO_PROTOCOL = 3;
0112:            protected static final int POST_PROTOCOL = 1;
0113:            protected static final int GET_PROTOCOL = 2;
0114:
0115:            protected int protocol = AUTO_PROTOCOL; // visible for transaction
0116:            protected Authenticator auth = null; // visible for transaction
0117:
0118:            private int bufferSize = 10;
0119:            private int timeout = 10000;
0120:            private final boolean tryGZIP;
0121:            protected WFSStrategy strategy;
0122:
0123:            protected String encoding = "UTF-8";
0124:
0125:            private boolean lenient;
0126:
0127:            /**
0128:             * Construct <code>WFSDataStore</code>.
0129:             *
0130:             * Should NEVER be called!
0131:             */
0132:            private WFSDataStore() {
0133:                // not called
0134:                tryGZIP = true;
0135:            }
0136:
0137:            protected WFSDataStore(URL host, Boolean protocol, String username,
0138:                    String password, int timeout, int buffer, boolean tryGZIP,
0139:                    boolean lenient, String encoding) throws SAXException,
0140:                    IOException {
0141:                this (host, protocol, username, password, timeout, buffer,
0142:                        tryGZIP, lenient);
0143:                if (encoding != null) {
0144:                    this .encoding = encoding;
0145:                }
0146:            }
0147:
0148:            /**
0149:             * Construct <code>WFSDataStore</code>.
0150:             *
0151:             * @param host - may not yet be a capabilities url
0152:             * @param protocol - true,false,null (post,get,auto)
0153:             * @param username - iff password
0154:             * @param password - iff username
0155:             * @param timeout - default 3000 (ms)
0156:             * @param buffer - default 10 (features)
0157:             * @param tryGZIP - indicates to use GZIP if server supports it.
0158:             * 
0159:             * @throws SAXException
0160:             * @throws IOException
0161:             */
0162:            protected WFSDataStore(URL host, Boolean protocol, String username,
0163:                    String password, int timeout, int buffer, boolean tryGZIP)
0164:                    throws SAXException, IOException {
0165:                this (host, protocol, username, password, timeout, buffer,
0166:                        tryGZIP, false);
0167:            }
0168:
0169:            /**
0170:             * Construct <code>WFSDataStore</code>.
0171:             *
0172:             * @param host - may not yet be a capabilities url
0173:             * @param protocol - true,false,null (post,get,auto)
0174:             * @param username - iff password
0175:             * @param password - iff username
0176:             * @param timeout - default 3000 (ms)
0177:             * @param buffer - default 10 (features)
0178:             * @param tryGZIP - indicates to use GZIP if server supports it.
0179:             * @param lenient - if true the parsing will be very forgiving to bad data.  Errors will be logged rather than exceptions.
0180:             * 
0181:             * @throws SAXException
0182:             * @throws IOException
0183:             */
0184:            protected WFSDataStore(URL host, Boolean protocol, String username,
0185:                    String password, int timeout, int buffer, boolean tryGZIP,
0186:                    boolean lenient) throws SAXException, IOException {
0187:                super (true);
0188:
0189:                this .lenient = lenient;
0190:                if ((username != null) && (password != null)) {
0191:                    auth = new WFSAuthenticator(username, password);
0192:                }
0193:
0194:                if (protocol == null) {
0195:                    this .protocol = AUTO_PROTOCOL;
0196:                } else {
0197:                    if (protocol.booleanValue()) {
0198:                        this .protocol = POST_PROTOCOL;
0199:                    } else {
0200:                        this .protocol = GET_PROTOCOL;
0201:                    }
0202:                }
0203:
0204:                this .timeout = timeout;
0205:                this .bufferSize = buffer;
0206:                this .tryGZIP = tryGZIP;
0207:                findCapabilities(host);
0208:                determineCorrectStrategy(host);
0209:            }
0210:
0211:            private void determineCorrectStrategy(URL host) {
0212:                if (host.toString().indexOf("mapserv") != -1)
0213:                    strategy = new MapServerWFSStrategy(this );
0214:                else
0215:                    strategy = new StrictWFSStrategy(this );
0216:            }
0217:
0218:            private void findCapabilities(URL host) throws SAXException,
0219:                    IOException {
0220:
0221:                Object t = null;
0222:                Map hints = new HashMap();
0223:                hints.put(DocumentFactory.VALIDATION_HINT, Boolean.FALSE);
0224:
0225:                if ((protocol & GET_PROTOCOL) == GET_PROTOCOL) {
0226:                    HttpURLConnection hc = getConnection(
0227:                            createGetCapabilitiesRequest(host), auth, false);
0228:                    InputStream is = getInputStream(hc);
0229:                    t = DocumentFactory.getInstance(is, hints,
0230:                            WFSDataStoreFactory.logger.getLevel());
0231:                }
0232:
0233:                if ((false == (t instanceof  WFSCapabilities))
0234:                        && ((protocol & POST_PROTOCOL) == POST_PROTOCOL)) {
0235:                    HttpURLConnection hc = getConnection(host, auth, true);
0236:
0237:                    // write request
0238:                    Writer osw = getOutputStream(hc);
0239:                    hints.put(DocumentWriter.BASE_ELEMENT, WFSSchema
0240:                            .getInstance().getElements()[0]); // GetCapabilities
0241:
0242:                    try {
0243:                        DocumentWriter.writeDocument((Object) null, WFSSchema
0244:                                .getInstance(), osw, hints);
0245:                    } catch (OperationNotSupportedException e) {
0246:                        WFSDataStoreFactory.logger.warning(e.getMessage());
0247:                        throw new SAXException(e);
0248:                    }
0249:
0250:                    osw.flush();
0251:                    osw.close();
0252:
0253:                    InputStream is = getInputStream(hc);
0254:                    t = DocumentFactory.getInstance(is, hints,
0255:                            WFSDataStoreFactory.logger.getLevel());
0256:                }
0257:
0258:                if (t instanceof  WFSCapabilities) {
0259:                    capabilities = (WFSCapabilities) t;
0260:                } else {
0261:                    throw new SAXException(
0262:                            "The specified URL Should have returned a 'WFSCapabilities' object. Returned a "
0263:                                    + ((t == null) ? "null value."
0264:                                            : (t.getClass().getName() + " instance.")));
0265:                }
0266:            }
0267:
0268:            protected HttpURLConnection getConnection(URL url,
0269:                    Authenticator auth, boolean isPost) throws IOException {
0270:
0271:                HttpURLConnection connection = (HttpURLConnection) url
0272:                        .openConnection();
0273:
0274:                if (isPost) {
0275:                    connection.setRequestMethod("POST");
0276:                    connection.setDoOutput(true);
0277:                    connection.setRequestProperty("Content-type",
0278:                            "text/xml, application/xml");
0279:                } else {
0280:                    connection.setRequestMethod("GET");
0281:                }
0282:                connection.setDoInput(true);
0283:                /*
0284:                 * FIXME this could breaks uDig. Not quite sure what to do otherwise.
0285:                 * Maybe have a mechanism that would allow an authenticator to ask the 
0286:                 * datastore itself for a previously supplied user/pass.
0287:                 */
0288:                if (auth != null) {
0289:                    synchronized (Authenticator.class) {
0290:                        Authenticator.setDefault(auth);
0291:                        connection.connect();
0292:                        Authenticator.setDefault(null);
0293:                    }
0294:                }
0295:
0296:                if (this .tryGZIP) {
0297:                    connection.addRequestProperty("Accept-Encoding", "gzip");
0298:                }
0299:
0300:                return connection;
0301:            }
0302:
0303:            protected static URL createGetCapabilitiesRequest(URL host) {
0304:                if (host == null) {
0305:                    return null;
0306:                }
0307:
0308:                String url = host.toString();
0309:
0310:                if (host.getQuery() == null) {
0311:                    url += "?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetCapabilities";
0312:                } else {
0313:                    String t = host.getQuery().toUpperCase();
0314:
0315:                    if (t.indexOf("SERVICE") == -1) {
0316:                        url += "&SERVICE=WFS";
0317:                    }
0318:
0319:                    if (t.indexOf("VERSION") == -1) {
0320:                        url += "&VERSION=1.0.0";
0321:                    }
0322:
0323:                    if (t.indexOf("REQUEST") == -1) {
0324:                        url += "&REQUEST=GetCapabilities";
0325:                    }
0326:                }
0327:
0328:                try {
0329:                    return new URL(url);
0330:                } catch (MalformedURLException e) {
0331:                    WFSDataStoreFactory.logger.warning(e.toString());
0332:
0333:                    return host;
0334:                }
0335:            }
0336:
0337:            private String[] typeNames = null;
0338:            private Map featureTypeCache = new HashMap();
0339:
0340:            private Map fidMap = new HashMap();
0341:
0342:            private Map xmlSchemaCache = new HashMap();
0343:
0344:            /**
0345:             * @see org.geotools.data.AbstractDataStore#getTypeNames()
0346:             */
0347:            public String[] getTypeNames() {
0348:                if (typeNames == null) {
0349:                    List l = capabilities.getFeatureTypes();
0350:                    typeNames = new String[l.size()];
0351:
0352:                    for (int i = 0; i < l.size(); i++) {
0353:                        typeNames[i] = ((FeatureSetDescription) l.get(i))
0354:                                .getName();
0355:                    }
0356:                }
0357:                // protect the cache against external modifications
0358:                String[] retVal = new String[typeNames.length];
0359:                System.arraycopy(typeNames, 0, retVal, 0, typeNames.length);
0360:                return retVal;
0361:            }
0362:
0363:            /**
0364:             * DOCUMENT ME!
0365:             *
0366:             * @param typeName DOCUMENT ME!
0367:             *
0368:             * @return DOCUMENT ME!
0369:             *
0370:             * @throws IOException
0371:             *
0372:             * @see org.geotools.data.AbstractDataStore#getSchema(java.lang.String)
0373:             */
0374:            public FeatureType getSchema(String typeName) throws IOException {
0375:                if (featureTypeCache.containsKey(typeName)) {
0376:                    return (FeatureType) featureTypeCache.get(typeName);
0377:                }
0378:
0379:                // TODO sanity check for request with capabilities obj
0380:
0381:                FeatureType t = null;
0382:                SAXException sax = null;
0383:                IOException io = null;
0384:                if (((protocol & POST_PROTOCOL) == POST_PROTOCOL)
0385:                        && (t == null)) {
0386:                    try {
0387:                        t = getSchemaPost(typeName);
0388:                    } catch (SAXException e) {
0389:                        WFSDataStoreFactory.logger.warning(e.toString());
0390:                        sax = e;
0391:                    } catch (IOException e) {
0392:                        WFSDataStoreFactory.logger.warning(e.toString());
0393:                        io = e;
0394:                    }
0395:                }
0396:
0397:                if (((protocol & GET_PROTOCOL) == GET_PROTOCOL) && (t == null)) {
0398:                    try {
0399:                        t = getSchemaGet(typeName);
0400:                    } catch (SAXException e) {
0401:                        WFSDataStoreFactory.logger.warning(e.toString());
0402:                        sax = e;
0403:                    } catch (IOException e) {
0404:                        WFSDataStoreFactory.logger.warning(e.toString());
0405:                        io = e;
0406:                    }
0407:                }
0408:
0409:                if (t == null && sax != null)
0410:                    throw new DataSourceException(sax);
0411:
0412:                if (t == null && io != null)
0413:                    throw io;
0414:
0415:                //set crs?
0416:                FeatureSetDescription fsd = WFSCapabilities
0417:                        .getFeatureSetDescription(capabilities, typeName);
0418:                String crsName = null;
0419:                String ftName = null;
0420:                if (fsd != null) {
0421:                    crsName = fsd.getSRS();
0422:                    ftName = fsd.getName();
0423:
0424:                    CoordinateReferenceSystem crs;
0425:                    try {
0426:                        if (crsName != null) {
0427:                            crs = CRS.decode(crsName);
0428:                            t = WFSFeatureTypeTransformer.transform(t, crs);
0429:                        }
0430:                    } catch (FactoryException e) {
0431:                        WFSDataStoreFactory.logger.warning(e.getMessage());
0432:                    } catch (SchemaException e) {
0433:                        WFSDataStoreFactory.logger.warning(e.getMessage());
0434:                    }
0435:                }
0436:
0437:                if (ftName != null) {
0438:                    try {
0439:                        t = FeatureTypeBuilder.newFeatureType(t
0440:                                .getAttributeTypes(), ftName == null ? typeName
0441:                                : ftName, t.getNamespace(), t.isAbstract(), t
0442:                                .getAncestors(), t.getDefaultGeometry());
0443:
0444:                    } catch (SchemaException e1) {
0445:                        WFSDataStoreFactory.logger.warning(e1.getMessage());
0446:                    }
0447:                }
0448:                try {
0449:                    URL url = getDescribeFeatureTypeURLGet(typeName);
0450:                    if (url != null) {
0451:                        t = new WFSFeatureType(t, new URI(url.toString()));
0452:                    }
0453:                } catch (URISyntaxException e) {
0454:                    throw (RuntimeException) new RuntimeException(e);
0455:                }
0456:                if (t != null) {
0457:                    featureTypeCache.put(typeName, t);
0458:                }
0459:
0460:                return t;
0461:            }
0462:
0463:            //  protected for testing
0464:            protected FeatureType getSchemaGet(String typeName)
0465:                    throws SAXException, IOException {
0466:                URL getUrl = getDescribeFeatureTypeURLGet(typeName);
0467:                Logging.getLogger("org.geotools.data.communication").fine(
0468:                        "Output: " + getUrl);
0469:                if (getUrl == null)
0470:                    return null;
0471:                HttpURLConnection hc = getConnection(getUrl, auth, false);
0472:
0473:                InputStream is = getInputStream(hc);
0474:                Schema schema;
0475:                try {
0476:                    schema = SchemaFactory.getInstance(null, is);
0477:                } finally {
0478:                    is.close();
0479:                }
0480:                return parseDescribeFeatureTypeResponse(typeName, schema);
0481:            }
0482:
0483:            private URL getDescribeFeatureTypeURLGet(String typeName)
0484:                    throws MalformedURLException {
0485:                URL getUrl = capabilities.getDescribeFeatureType().getGet();
0486:                Logging.getLogger("org.geotools.data.communication").fine(
0487:                        "Output: " + getUrl);
0488:
0489:                if (getUrl == null) {
0490:                    return null;
0491:                }
0492:
0493:                String query = getUrl.getQuery();
0494:                query = query == null ? null : query.toUpperCase();
0495:                String url = getUrl.toString();
0496:
0497:                if ((query == null) || "".equals(query)) {
0498:                    if ((url == null) || !url.endsWith("?")) {
0499:                        url += "?";
0500:                    }
0501:
0502:                    url += "SERVICE=WFS";
0503:                } else {
0504:                    if (query.indexOf("SERVICE=WFS") == -1) {
0505:                        url += "&SERVICE=WFS";
0506:                    }
0507:                }
0508:
0509:                if ((query == null) || (query.indexOf("VERSION") == -1)) {
0510:                    url += "&VERSION=1.0.0";
0511:                }
0512:
0513:                if ((query == null) || (query.indexOf("REQUEST") == -1)) {
0514:                    url += "&REQUEST=DescribeFeatureType";
0515:                }
0516:
0517:                url += ("&TYPENAME=" + typeName);
0518:
0519:                getUrl = new URL(url);
0520:                return getUrl;
0521:            }
0522:
0523:            static FeatureType parseDescribeFeatureTypeResponse(
0524:                    String typeName, Schema schema) throws SAXException {
0525:                Element[] elements = schema.getElements();
0526:
0527:                if (elements == null) {
0528:                    return null; // not found
0529:                }
0530:
0531:                Element element = null;
0532:
0533:                String ttname = typeName.substring(typeName.indexOf(":") + 1);
0534:
0535:                for (int i = 0; (i < elements.length) && (element == null); i++) {
0536:                    // HACK -- namspace related -- should be checking ns as opposed to removing prefix
0537:                    if (typeName.equals(elements[i].getName())
0538:                            || ttname.equals(elements[i].getName())) {
0539:                        element = elements[i];
0540:                    }
0541:                }
0542:
0543:                if (element == null) {
0544:                    return null;
0545:                }
0546:
0547:                FeatureType ft = GMLComplexTypes.createFeatureType(element);
0548:
0549:                return ft;
0550:            }
0551:
0552:            // protected for testing
0553:            protected FeatureType getSchemaPost(String typeName)
0554:                    throws IOException, SAXException {
0555:                URL postUrl = capabilities.getDescribeFeatureType().getPost();
0556:
0557:                if (postUrl == null) {
0558:                    return null;
0559:                }
0560:
0561:                HttpURLConnection hc = getConnection(postUrl, auth, true);
0562:
0563:                // write request
0564:                Writer osw = getOutputStream(hc);
0565:                Map hints = new HashMap();
0566:                hints.put(DocumentWriter.BASE_ELEMENT, WFSSchema.getInstance()
0567:                        .getElements()[1]); // DescribeFeatureType
0568:                List l = capabilities.getFeatureTypes();
0569:                Iterator it = l.iterator();
0570:                URI uri = null;
0571:                while (it.hasNext() && uri == null) {
0572:                    FeatureSetDescription fsd = (FeatureSetDescription) it
0573:                            .next();
0574:                    if (typeName.equals(fsd.getName()))
0575:                        uri = fsd.getNamespace();
0576:                }
0577:                if (uri != null)
0578:                    hints.put(DocumentWriter.SCHEMA_ORDER, new String[] {
0579:                            WFSSchema.NAMESPACE.toString(), uri.toString() });
0580:
0581:                hints.put(DocumentWriter.ENCODING, encoding);
0582:                try {
0583:                    DocumentWriter.writeDocument(new String[] { typeName },
0584:                            WFSSchema.getInstance(), osw, hints);
0585:                } catch (OperationNotSupportedException e) {
0586:                    WFSDataStoreFactory.logger.warning(e.getMessage());
0587:                    throw new SAXException(e);
0588:                }
0589:
0590:                osw.flush();
0591:                osw.close();
0592:                InputStream is = getInputStream(hc);
0593:
0594:                Schema schema;
0595:                try {
0596:                    schema = SchemaFactory.getInstance(null, is);
0597:                } finally {
0598:                    is.close();
0599:                }
0600:
0601:                return parseDescribeFeatureTypeResponse(typeName, schema);
0602:            }
0603:
0604:            //  protected for testing
0605:            protected FeatureReader getFeatureReaderGet(Query request,
0606:                    Transaction transaction)
0607:                    throws UnsupportedEncodingException, IOException,
0608:                    SAXException {
0609:                URL getUrl = capabilities.getGetFeature().getGet();
0610:
0611:                if (getUrl == null) {
0612:                    return null;
0613:                }
0614:
0615:                String query = getUrl.getQuery();
0616:                query = query == null ? null : query.toUpperCase();
0617:                String url = getUrl.toString();
0618:
0619:                if ((query == null) || "".equals(query)) {
0620:                    if ((url == null) || !url.endsWith("?")) {
0621:                        url += "?";
0622:                    }
0623:
0624:                    url += "SERVICE=WFS";
0625:                } else {
0626:                    if (query.indexOf("SERVICE=WFS") == -1) {
0627:                        url += "&SERVICE=WFS";
0628:                    }
0629:                }
0630:
0631:                if ((query == null) || (query.indexOf("VERSION") == -1)) {
0632:                    url += "&VERSION=1.0.0";
0633:                }
0634:
0635:                if ((query == null) || (query.indexOf("REQUEST") == -1)) {
0636:                    url += "&REQUEST=GetFeature";
0637:                }
0638:
0639:                if (request != null) {
0640:                    if (request.getMaxFeatures() != Query.DEFAULT_MAX) {
0641:                        url += ("&MAXFEATURES=" + request.getMaxFeatures());
0642:                    }
0643:
0644:                    if (request.getFilter() != null) {
0645:                        if (Filters.getFilterType(request.getFilter()) == FilterType.GEOMETRY_BBOX) {
0646:                            String bb = printBBoxGet(((GeometryFilter) request
0647:                                    .getFilter()), request.getTypeName());
0648:                            if (bb != null)
0649:                                url += ("&BBOX=" + URLEncoder.encode(bb,
0650:                                        this .encoding));
0651:                        } else {
0652:                            if (Filters.getFilterType(request.getFilter()) == FilterType.FID) {
0653:                                FidFilter ff = (FidFilter) request.getFilter();
0654:
0655:                                if ((ff.getFids() != null)
0656:                                        && (ff.getFids().length > 0)) {
0657:                                    url += ("&FEATUREID=" + ff.getFids()[0]);
0658:
0659:                                    for (int i = 1; i < ff.getFids().length; i++) {
0660:                                        url += ("," + ff.getFids()[i]);
0661:                                    }
0662:                                }
0663:                            } else {
0664:                                // rest
0665:                                if (request.getFilter() != Filter.INCLUDE
0666:                                        && request.getFilter() != Filter.EXCLUDE) {
0667:                                    url += "&FILTER="
0668:                                            + URLEncoder.encode(
0669:                                                    printFilter(request
0670:                                                            .getFilter()),
0671:                                                    this .encoding);
0672:                                }
0673:                            }
0674:                        }
0675:                    }
0676:                }
0677:
0678:                url += ("&TYPENAME=" + URLEncoder.encode(request.getTypeName(),
0679:                        this .encoding));
0680:
0681:                Logging.getLogger("org.geotools.data.wfs").fine(url);
0682:                Logging.getLogger("org.geotools.data.communication").fine(
0683:                        "Output: " + url);
0684:                getUrl = new URL(url);
0685:                HttpURLConnection hc = getConnection(getUrl, auth, false);
0686:
0687:                InputStream is = getInputStream(hc);
0688:                WFSTransactionState ts = null;
0689:
0690:                if (!(transaction == Transaction.AUTO_COMMIT)) {
0691:                    ts = (WFSTransactionState) transaction.getState(this );
0692:
0693:                    if (ts == null) {
0694:                        ts = new WFSTransactionState(this );
0695:                        transaction.putState(this , ts);
0696:                    }
0697:                }
0698:
0699:                WFSFeatureType schema = (WFSFeatureType) getSchema(request
0700:                        .getTypeName());
0701:
0702:                FeatureType featureType;
0703:                try {
0704:                    featureType = DataUtilities.createSubType(schema.delegate,
0705:                            request.getPropertyNames(), request
0706:                                    .getCoordinateSystem());
0707:                } catch (SchemaException e) {
0708:                    featureType = schema.delegate;
0709:                }
0710:                WFSFeatureReader ft = WFSFeatureReader.getFeatureReader(is,
0711:                        bufferSize, timeout, ts,
0712:                        new WFSFeatureType(schema.delegate, schema
0713:                                .getSchemaURI(), lenient));
0714:
0715:                if (!featureType.equals(ft.getFeatureType())) {
0716:                    LOGGER
0717:                            .fine("Recasting feature type to subtype by using a ReTypeFeatureReader");
0718:                    return new ReTypeFeatureReader(ft, featureType, false);
0719:                } else
0720:                    return ft;
0721:
0722:            }
0723:
0724:            Writer getOutputStream(HttpURLConnection hc) throws IOException {
0725:                OutputStream os = hc.getOutputStream();
0726:
0727:                Writer w = new OutputStreamWriter(os);
0728:                // write request
0729:                Logger logger = Logging.getLogger("org.geotools.data.wfs");
0730:                if (logger.isLoggable(Level.FINE)) {
0731:                    w = new LogWriterDecorator(w, logger, Level.FINE);
0732:                }
0733:                // special logger for communication information only.
0734:                logger = Logging.getLogger("org.geotools.data.communication");
0735:                if (logger.isLoggable(Level.FINE)) {
0736:                    w = new LogWriterDecorator(w, logger, Level.FINE);
0737:                }
0738:                return w;
0739:            }
0740:
0741:            /**
0742:             * If the field useGZIP is true Adds gzip to the connection accept-encoding property and creates a gzip inputstream 
0743:             * (if server supports it).  Otherwise returns a normal buffered input stream.  
0744:             * @param hc the connection to use to create the stream
0745:             * @return an input steam from the provided connection
0746:             */
0747:            InputStream getInputStream(HttpURLConnection hc) throws IOException {
0748:                InputStream is = hc.getInputStream();
0749:
0750:                if (tryGZIP) {
0751:                    if (hc.getContentEncoding() != null
0752:                            && hc.getContentEncoding().indexOf("gzip") != -1) {
0753:                        is = new GZIPInputStream(is);
0754:                    }
0755:                }
0756:                is = new BufferedInputStream(is);
0757:                if (WFSDataStoreFactory.logger.isLoggable(Level.FINE)) {
0758:                    is = new LogInputStream(is, WFSDataStoreFactory.logger,
0759:                            Level.FINE);
0760:                }
0761:                // special logger for communication information only.
0762:                Logger logger = Logging
0763:                        .getLogger("org.geotools.data.communication");
0764:                if (logger.isLoggable(Level.FINE)) {
0765:                    is = new LogInputStream(is, logger, Level.FINE);
0766:                }
0767:                return is;
0768:            }
0769:
0770:            private String printFilter(Filter f) throws IOException,
0771:                    SAXException {
0772:                // ogc filter
0773:                Map hints = new HashMap();
0774:                hints.put(DocumentWriter.BASE_ELEMENT, FilterSchema
0775:                        .getInstance().getElements()[2]); // Filter
0776:
0777:                StringWriter w = new StringWriter();
0778:
0779:                try {
0780:                    DocumentWriter.writeFragment(f, FilterSchema.getInstance(),
0781:                            w, hints);
0782:                } catch (OperationNotSupportedException e) {
0783:                    WFSDataStoreFactory.logger.warning(e.toString());
0784:                    throw new SAXException(e);
0785:                }
0786:
0787:                return w.toString();
0788:            }
0789:
0790:            private String printBBoxGet(GeometryFilter gf, String typename)
0791:                    throws IOException {
0792:                Envelope e = null;
0793:
0794:                if (gf.getLeftGeometry().getType() == ExpressionType.LITERAL_GEOMETRY) {
0795:                    e = ((Geometry) ((LiteralExpression) gf.getLeftGeometry())
0796:                            .getLiteral()).getEnvelopeInternal();
0797:                } else {
0798:                    if (gf.getRightGeometry().getType() == ExpressionType.LITERAL_GEOMETRY) {
0799:                        LiteralExpression literal = (LiteralExpression) gf
0800:                                .getRightGeometry();
0801:                        Geometry geometry = (Geometry) literal.getLiteral();
0802:                        e = geometry.getEnvelopeInternal();
0803:                    } else {
0804:                        throw new IOException("Cannot encode BBOX:" + gf);
0805:                    }
0806:                }
0807:
0808:                if (e == null || e.isNull())
0809:                    return null;
0810:
0811:                // Cannot check against layer bbounding box because they may be in different CRS
0812:                // We could insert ReferencedEnvelope fun here - note a check is already performed
0813:                // as part clipping the request bounding box.
0814:
0815:                /*
0816:                // find layer's bbox
0817:                Envelope lbb = null;
0818:                if(capabilities != null && capabilities.getFeatureTypes() != null && typename!=null && !"".equals(typename)){
0819:                    List fts = capabilities.getFeatureTypes();
0820:                    if(!fts.isEmpty()){
0821:                        for(Iterator i=fts.iterator();i.hasNext() && lbb == null;){
0822:                            FeatureSetDescription fsd = (FeatureSetDescription)i.next();
0823:                            if(fsd!=null && typename.equals(fsd.getName())){
0824:                                lbb = fsd.getLatLongBoundingBox();
0825:                            }
0826:                        }
0827:                    }
0828:                }
0829:                if(lbb == null || lbb.contains(e))
0830:                 */
0831:                return e.getMinX() + "," + e.getMinY() + "," + e.getMaxX()
0832:                        + "," + e.getMaxY();
0833:                //return null;
0834:            }
0835:
0836:            //  protected for testing
0837:            protected FeatureReader getFeatureReaderPost(Query query,
0838:                    Transaction transaction) throws SAXException, IOException {
0839:                URL postUrl = capabilities.getGetFeature().getPost();
0840:
0841:                if (postUrl == null) {
0842:                    return null;
0843:                }
0844:
0845:                HttpURLConnection hc = getConnection(postUrl, auth, true);
0846:
0847:                Writer w = getOutputStream(hc);
0848:
0849:                Map hints = new HashMap();
0850:                hints.put(DocumentWriter.BASE_ELEMENT, WFSSchema.getInstance()
0851:                        .getElements()[2]); // GetFeature
0852:                hints.put(DocumentWriter.ENCODING, encoding);
0853:                try {
0854:                    DocumentWriter.writeDocument(query,
0855:                            WFSSchema.getInstance(), w, hints);
0856:                } catch (OperationNotSupportedException e) {
0857:                    WFSDataStoreFactory.logger.warning(e.toString());
0858:                    throw new SAXException(e);
0859:                } finally {
0860:                    w.flush();
0861:                    w.close();
0862:                }
0863:
0864:                // JE: permit possibility for GZipped data.
0865:                InputStream is = getInputStream(hc);
0866:
0867:                WFSTransactionState ts = null;
0868:
0869:                if (!(transaction == Transaction.AUTO_COMMIT)) {
0870:                    ts = (WFSTransactionState) transaction.getState(this );
0871:
0872:                    if (ts == null) {
0873:                        ts = new WFSTransactionState(this );
0874:                        transaction.putState(this , ts);
0875:                    }
0876:                }
0877:                WFSFeatureType schema = (WFSFeatureType) getSchema(query
0878:                        .getTypeName());
0879:
0880:                FeatureType featureType;
0881:                try {
0882:                    featureType = DataUtilities.createSubType(schema.delegate,
0883:                            query.getPropertyNames(), query
0884:                                    .getCoordinateSystem());
0885:                } catch (SchemaException e) {
0886:                    featureType = schema.delegate;
0887:                }
0888:
0889:                WFSFeatureReader ft = WFSFeatureReader.getFeatureReader(is,
0890:                        bufferSize, timeout, ts,
0891:                        new WFSFeatureType(schema.delegate, schema
0892:                                .getSchemaURI(), lenient));
0893:
0894:                if (!featureType.equals(ft.getFeatureType())) {
0895:                    LOGGER
0896:                            .fine("Recasting feature type to subtype by using a ReTypeFeatureReader");
0897:                    return new ReTypeFeatureReader(ft, featureType, false);
0898:                } else
0899:                    return ft;
0900:            }
0901:
0902:            protected FeatureReader getFeatureReader(String typeName)
0903:                    throws IOException {
0904:                return getFeatureReader(typeName, new DefaultQuery(typeName));
0905:            }
0906:
0907:            protected FeatureReader getFeatureReader(String typeName,
0908:                    Query query) throws IOException {
0909:                if ((query.getTypeName() == null)
0910:                        || !query.getTypeName().equals(typeName)) {
0911:                    Query q = new DefaultQuery(query);
0912:                    ((DefaultQuery) q).setTypeName(typeName);
0913:
0914:                    return getFeatureReader(q, Transaction.AUTO_COMMIT);
0915:                }
0916:
0917:                return getFeatureReader(query, Transaction.AUTO_COMMIT);
0918:            }
0919:
0920:            /**
0921:             * @see org.geotools.data.DataStore#getFeatureReader(org.geotools.data.Query, org.geotools.data.Transaction)
0922:             */
0923:            public FeatureReader getFeatureReader(Query query,
0924:                    Transaction transaction) throws IOException {
0925:                return strategy.getFeatureReader(query, transaction);
0926:            }
0927:
0928:            /* (non-Javadoc)
0929:             * @see org.geotools.data.AbstractDataStore#getBounds(org.geotools.data.Query)
0930:             */
0931:            protected Envelope getBounds(Query query) throws IOException {
0932:                if ((query == null) || (query.getTypeName() == null)) {
0933:                    return super .getBounds(query);
0934:                }
0935:
0936:                List fts = capabilities.getFeatureTypes(); // FeatureSetDescription
0937:                Iterator i = fts.iterator();
0938:                String desiredType = query.getTypeName().substring(
0939:                        query.getTypeName().indexOf(":") + 1);
0940:
0941:                while (i.hasNext()) {
0942:                    FeatureSetDescription fsd = (FeatureSetDescription) i
0943:                            .next();
0944:                    String fsdName = (fsd.getName() == null) ? null : fsd
0945:                            .getName()
0946:                            .substring(fsd.getName().indexOf(":") + 1);
0947:
0948:                    if (desiredType.equals(fsdName)) {
0949:                        Envelope env = fsd.getLatLongBoundingBox();
0950:
0951:                        ReferencedEnvelope referencedEnvelope = new ReferencedEnvelope(
0952:                                env, DefaultGeographicCRS.WGS84);
0953:
0954:                        try {
0955:                            return referencedEnvelope.transform(CRS.decode(fsd
0956:                                    .getSRS()), true);
0957:                        } catch (NoSuchAuthorityCodeException e) {
0958:                            return referencedEnvelope;
0959:                        } catch (TransformException e) {
0960:                            return referencedEnvelope;
0961:                        } catch (FactoryException e) {
0962:                            return referencedEnvelope;
0963:                        }
0964:                    }
0965:                }
0966:
0967:                return super .getBounds(query);
0968:            }
0969:
0970:            protected Filter[] splitFilters(Query q, Transaction t)
0971:                    throws IOException {
0972:                // have to figure out which part of the request the server is capable of after removing the parts in the update / delete actions
0973:                // [server][post]
0974:                if (q.getFilter() == null)
0975:                    return new Filter[] { Filter.INCLUDE, Filter.INCLUDE };
0976:                if (q.getTypeName() == null || t == null)
0977:                    return new Filter[] { Filter.INCLUDE, q.getFilter() };
0978:
0979:                FeatureType ft = getSchema(q.getTypeName());
0980:
0981:                List fts = capabilities.getFeatureTypes(); //FeatureSetDescription
0982:                boolean found = false;
0983:                for (int i = 0; i < fts.size(); i++)
0984:                    if (fts.get(i) != null) {
0985:                        FeatureSetDescription fsd = (FeatureSetDescription) fts
0986:                                .get(i);
0987:                        if (ft.getTypeName().equals(fsd.getName())) {
0988:                            found = true;
0989:                        } else {
0990:                            String fsdName = (fsd.getName() == null) ? null
0991:                                    : fsd.getName().substring(
0992:                                            fsd.getName().indexOf(":") + 1);
0993:                            if (ft.getTypeName().equals(fsdName)) {
0994:                                found = true;
0995:                            }
0996:                        }
0997:                    }
0998:
0999:                if (!found) {
1000:                    WFSDataStoreFactory.logger
1001:                            .warning("Could not find typeName: "
1002:                                    + ft.getTypeName());
1003:                    return new Filter[] { Filter.INCLUDE, q.getFilter() };
1004:                }
1005:                WFSTransactionState state = (t == Transaction.AUTO_COMMIT) ? null
1006:                        : (WFSTransactionState) t.getState(this );
1007:                WFSTransactionAccessor transactionAccessor = null;
1008:                if (state != null)
1009:                    transactionAccessor = new WFSTransactionAccessor(state
1010:                            .getActions(ft.getTypeName()));
1011:                PostPreProcessFilterSplittingVisitor wfsfv = new PostPreProcessFilterSplittingVisitor(
1012:                        capabilities.getFilterCapabilities(), ft,
1013:                        transactionAccessor);
1014:
1015:                q.getFilter().accept(wfsfv, null);
1016:
1017:                Filter[] f = new Filter[2];
1018:                f[0] = wfsfv.getFilterPre(); // server
1019:                f[1] = wfsfv.getFilterPost();
1020:
1021:                return f;
1022:            }
1023:
1024:            /**
1025:             * @see org.geotools.data.AbstractDataStore#getUnsupportedFilter(java.lang.String,
1026:             *      org.geotools.filter.Filter)
1027:             */
1028:            protected Filter getUnsupportedFilter(String typeName, Filter filter) {
1029:                try {
1030:                    return splitFilters(new DefaultQuery(typeName, filter),
1031:                            Transaction.AUTO_COMMIT)[1];
1032:                } catch (IOException e) {
1033:                    return filter;
1034:                }
1035:            }
1036:
1037:            /**
1038:             * 
1039:             * @see org.geotools.data.DataStore#getFeatureSource(java.lang.String)
1040:             */
1041:            public FeatureSource getFeatureSource(String typeName)
1042:                    throws IOException {
1043:                if (capabilities.getTransaction() != null) {
1044:                    //			if(capabilities.getLockFeature()!=null){
1045:                    //				return new WFSFeatureLocking(this,getSchema(typeName));
1046:                    //			}
1047:                    return new WFSFeatureStore(this , typeName);
1048:                }
1049:
1050:                return new WFSFeatureSource(this , typeName);
1051:            }
1052:
1053:            /**
1054:             * Runs {@link FidFilterVisitor} on the filter and returns the result as long as transaction is not AUTO_COMMIT or null.
1055:             * @param filter filter to process.
1056:             * @return Runs {@link FidFilterVisitor} on the filter and returns the result as long as transaction is not AUTO_COMMIT or null.
1057:             */
1058:            public Filter processFilter(Filter filter) {
1059:                FidFilterVisitor visitor = new FidFilterVisitor(fidMap);
1060:                Filters.accept(filter, visitor);
1061:                return visitor.getProcessedFilter();
1062:            }
1063:
1064:            private static class WFSAuthenticator extends Authenticator {
1065:                private PasswordAuthentication pa;
1066:
1067:                private WFSAuthenticator() {
1068:                    // not called
1069:                }
1070:
1071:                /**
1072:                 * 
1073:                 * @param user
1074:                 * @param pass
1075:                 * @param host
1076:                 */
1077:                public WFSAuthenticator(String user, String pass) {
1078:                    pa = new PasswordAuthentication(user, pass.toCharArray());
1079:                }
1080:
1081:                protected PasswordAuthentication getPasswordAuthentication() {
1082:                    return pa;
1083:                }
1084:            }
1085:
1086:            /**
1087:             * Adds a new fid mapping to the fid map. 
1088:             * @param original the before fid
1089:             * @param finalFid the final fid;
1090:             */
1091:            public synchronized void addFidMapping(String original,
1092:                    String finalFid) {
1093:                if (original == null)
1094:                    throw new NullPointerException();
1095:                fidMap.put(original, finalFid);
1096:            }
1097:
1098:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.