Source Code Cross Referenced for XmlSchemaEncoder.java in  » GIS » GeoServer » org » geoserver » wfs » xml » v1_0_0 » 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 » GeoServer » org.geoserver.wfs.xml.v1_0_0 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002:         * This code is licensed under the GPL 2.0 license, availible at the root
003:         * application directory.
004:         */
005:        package org.geoserver.wfs.xml.v1_0_0;
006:
007:        import net.opengis.wfs.DescribeFeatureTypeType;
008:
009:        import org.geoserver.ows.util.RequestUtils;
010:        import org.geoserver.ows.util.ResponseUtils;
011:        import org.geoserver.platform.Operation;
012:        import org.geoserver.platform.ServiceException;
013:        import org.geoserver.wfs.WFS;
014:        import org.geoserver.wfs.WFSDescribeFeatureTypeOutputFormat;
015:        import org.geoserver.wfs.WFSException;
016:        import org.geotools.feature.FeatureType;
017:        import org.geotools.gml.producer.FeatureTypeTransformer;
018:        import org.vfny.geoserver.global.Data;
019:        import org.vfny.geoserver.global.FeatureTypeInfo;
020:        import java.io.File;
021:        import java.io.FileInputStream;
022:        import java.io.IOException;
023:        import java.io.OutputStream;
024:        import java.io.StringWriter;
025:        import java.util.HashSet;
026:        import java.util.Iterator;
027:        import java.util.Set;
028:        import java.util.logging.Level;
029:        import java.util.logging.Logger;
030:        import javax.xml.transform.TransformerException;
031:
032:        public class XmlSchemaEncoder extends
033:                WFSDescribeFeatureTypeOutputFormat {
034:            /** Standard logging instance for class */
035:            private static final Logger LOGGER = org.geotools.util.logging.Logging
036:                    .getLogger("org.vfny.geoserver.responses");
037:
038:            // Initialize some generic GML information
039:            // ABSTRACT OUTSIDE CLASS, IF POSSIBLE
040:            private static final String SCHEMA_URI = "\"http://www.w3.org/2001/XMLSchema\"";
041:            private static final String XS_NAMESPACE = "\n  xmlns:xs="
042:                    + SCHEMA_URI;
043:            private static final String GML_URL = "\"http://www.opengis.net/gml\"";
044:            private static final String GML_NAMESPACE = "\n  xmlns:gml="
045:                    + GML_URL;
046:            private static final String ELEMENT_FORM_DEFAULT = "\n  elementFormDefault=\"qualified\"";
047:            private static final String ATTR_FORM_DEFAULT = "\n  attributeFormDefault=\"unqualified\" version=\"1.0\">";
048:            private static final String TARGETNS_PREFIX = "\n  targetNamespace=\"";
049:            private static final String TARGETNS_SUFFIX = "\" ";
050:
051:            /** Fixed return footer information */
052:            private static final String FOOTER = "\n</xs:schema>";
053:            WFS wfs;
054:            Data catalog;
055:
056:            public XmlSchemaEncoder(WFS wfs, Data catalog) {
057:                super ("XMLSCHEMA");
058:                this .wfs = wfs;
059:                this .catalog = catalog;
060:            }
061:
062:            public String getMimeType(Object value, Operation operation)
063:                    throws ServiceException {
064:                return "text/xml";
065:            }
066:
067:            protected void write(FeatureTypeInfo[] featureTypeInfos,
068:                    OutputStream output, Operation describeFeatureType)
069:                    throws IOException {
070:                //generates response, using general function
071:                String xmlResponse = generateTypes(featureTypeInfos,
072:                        (DescribeFeatureTypeType) describeFeatureType
073:                                .getParameters()[0]);
074:
075:                if (!wfs.isVerbose()) {
076:                    //strip out the formatting.  This is pretty much the only way we
077:                    //can do this, as the user files are going to have newline
078:                    //characters and whatnot, unless we can get rid of formatting
079:                    //when we read the file, which could be worth looking into if
080:                    //this slows things down.
081:                    xmlResponse = xmlResponse.replaceAll(">\n[ \\t\\n]*", ">");
082:                    xmlResponse = xmlResponse.replaceAll("\n[ \\t\\n]*", " ");
083:                }
084:
085:                byte[] content = xmlResponse.getBytes();
086:                output.write(content);
087:            }
088:
089:            /**
090:             * Internal method to generate the XML response object, using feature
091:             * types.
092:             *
093:             * @param wfsRequest The request object.
094:             *
095:             * @return The XMLSchema describing the features requested.
096:             *
097:             * @throws WFSException For any problems.
098:             */
099:            private final String generateTypes(FeatureTypeInfo[] infos,
100:                    DescribeFeatureTypeType request) throws IOException {
101:                // Initialize return information and intermediate return objects
102:                StringBuffer tempResponse = new StringBuffer();
103:
104:                tempResponse.append("<?xml version=\"1.0\" encoding=\""
105:                        + wfs.getCharSet().name() + "\"?>" + "\n<xs:schema ");
106:
107:                String proxifiedBaseUrl = RequestUtils.proxifiedBaseURL(request
108:                        .getBaseUrl(), wfs.getGeoServer().getProxyBaseUrl());
109:                //allSameType will throw WFSException if there are types that are not found.
110:                if (allSameType(infos)) {
111:                    //all the requested have the same namespace prefix, so return their
112:                    //schemas.
113:                    FeatureTypeInfo ftInfo = infos[0];
114:                    String targetNs = ftInfo.getNameSpace().getURI();
115:
116:                    //String targetNs = nsInfoType.getXmlns();
117:                    tempResponse.append(TARGETNS_PREFIX + targetNs
118:                            + TARGETNS_SUFFIX);
119:
120:                    //namespace
121:                    tempResponse.append("\n  " + "xmlns:"
122:                            + ftInfo.getNameSpace().getPrefix() + "=\""
123:                            + targetNs + "\"");
124:
125:                    //xmlns:" + nsPrefix + "=\"" + targetNs
126:                    //+ "\"");
127:                    tempResponse.append(GML_NAMESPACE);
128:                    tempResponse.append(XS_NAMESPACE);
129:                    tempResponse.append(ELEMENT_FORM_DEFAULT
130:                            + ATTR_FORM_DEFAULT);
131:
132:                    //request.getBaseUrl should actually be GeoServer.getSchemaBaseUrl()
133:                    //but that method is broken right now.  See the note there.
134:
135:                    //JD: need a good way to publish resources under a web url, at the 
136:                    // same time abstracting away the httpness of the service, for 
137:                    // now replacing the schemas.opengis.net
138:
139:                    //            tempResponse.append("\n\n<xs:import namespace=" + GML_URL
140:                    //                + " schemaLocation=\"" + request.getSchemaBaseUrl()
141:                    //                + "gml/2.1.2/feature.xsd\"/>\n\n");
142:                    tempResponse.append("\n\n<xs:import namespace="
143:                            + GML_URL
144:                            + " schemaLocation=\""
145:                            + ResponseUtils.appendPath(proxifiedBaseUrl,
146:                                    "schemas/gml/2.1.2.1/feature.xsd")
147:                            + "\"/>\n\n");
148:                    tempResponse.append(generateSpecifiedTypes(infos));
149:                } else {
150:                    //the featureTypes do not have all the same prefixes.
151:                    tempResponse.append(XS_NAMESPACE);
152:                    tempResponse.append(ELEMENT_FORM_DEFAULT
153:                            + ATTR_FORM_DEFAULT);
154:
155:                    Set prefixes = new HashSet();
156:
157:                    //iterate through the types, and make a set of their prefixes.
158:                    for (int i = 0; i < infos.length; i++) {
159:                        FeatureTypeInfo ftInfo = infos[i];
160:                        prefixes.add(ftInfo.getNameSpace().getPrefix());
161:                    }
162:
163:                    Iterator prefixIter = prefixes.iterator();
164:
165:                    while (prefixIter.hasNext()) {
166:                        //iterate through prefixes, and add the types that have that prefix.
167:                        String prefix = prefixIter.next().toString();
168:                        String wfsBaseUrl;
169:                        if (proxifiedBaseUrl.endsWith("/"))
170:                            wfsBaseUrl = proxifiedBaseUrl
171:                                    + request.getService().toLowerCase();
172:                        else
173:                            wfsBaseUrl = proxifiedBaseUrl + "/"
174:                                    + request.getService().toLowerCase();
175:                        tempResponse.append(getNSImport(prefix, infos,
176:                                wfsBaseUrl));
177:                    }
178:                }
179:
180:                tempResponse.append(FOOTER);
181:
182:                return tempResponse.toString();
183:            }
184:
185:            /**
186:             * Creates a import namespace element, for cases when requests contain
187:             * multiple namespaces, as you can not have more than one target
188:             * namespace.  See wfs spec. 8.3.1.  All the typeNames that have the
189:             * correct prefix are added to the import statement.
190:             *
191:             * @param prefix the namespace prefix, which must be mapped in the main
192:             *        ConfigInfo, for this import statement.
193:             * @param typeNames a list of all requested typeNames, only those that
194:             *        match the prefix will be a part of this import statement.
195:             * @param r DOCUMENT ME!
196:             *
197:             * @return The namespace element.
198:             */
199:            private StringBuffer getNSImport(String prefix,
200:                    FeatureTypeInfo[] infos, String baseUrl) {
201:                LOGGER.finer("prefix is " + prefix);
202:
203:                StringBuffer retBuffer = new StringBuffer(
204:                        "\n  <xs:import namespace=\"");
205:                String namespace = catalog.getNameSpace(prefix).getURI();
206:                retBuffer.append(namespace + "\"");
207:                retBuffer
208:                        .append("\n        schemaLocation=\""
209:                                + baseUrl
210:                                + "?request=DescribeFeatureType&amp;service=wfs&amp;version=1.0.0&amp;typeName=");
211:
212:                for (int i = 0; i < infos.length; i++) {
213:                    FeatureTypeInfo info = infos[i];
214:                    String typeName = info.getName();
215:
216:                    if (typeName.startsWith(prefix + ":")) {
217:                        retBuffer.append(typeName + ",");
218:                    }
219:
220:                    //JD: some of this logic should be fixed by poplulating the 
221:                    // info objects properly, double check
222:                    //            if (typeName.startsWith(prefix)
223:                    //                    || ((typeName.indexOf(':') == -1)
224:                    //                    && prefix.equals(r.getWFS().getData().getDefaultNameSpace()
225:                    //                                          .getPrefix()))) {
226:                    //                retBuffer.append(typeName + ",");
227:                    //            }
228:                }
229:
230:                retBuffer.deleteCharAt(retBuffer.length() - 1);
231:                retBuffer.append("\"/>");
232:
233:                return retBuffer;
234:            }
235:
236:            /**
237:             * Internal method to print just the requested types.  They should all be
238:             * in the same namespace, that handling should be done before.  This will
239:             * not do any namespace handling, just prints up either what's in the
240:             * schema file, or if it's not there then generates the types from their
241:             * FeatureTypes.  Also appends the global element so that the types can
242:             * substitute as features.
243:             *
244:             * @param requestedTypes The requested table names.
245:             * @param gs DOCUMENT ME!
246:             *
247:             * @return A string of the types printed.
248:             *
249:             * @throws WFSException DOCUMENT ME!
250:             *
251:             * @task REVISIT: We need a way to make sure the extension bases are
252:             *       correct. should likely add a field to the info.xml in the
253:             *       featureTypes folder, that optionally references an extension base
254:             *       (should it be same namespace? we could also probably just do an
255:             *       import on the extension base).  This function then would see if
256:             *       the typeInfo has an extension base, and would add or import the
257:             *       file appropriately, and put the correct substitution group in
258:             *       this function.
259:             */
260:            private String generateSpecifiedTypes(FeatureTypeInfo[] infos) {
261:                //TypeRepository repository = TypeRepository.getInstance();
262:                String tempResponse = new String();
263:
264:                String generatedType = new String();
265:                Set validTypes = new HashSet();
266:
267:                // Loop through requested tables to add element types
268:                for (int i = 0; i < infos.length; i++) {
269:                    FeatureTypeInfo ftInfo = (FeatureTypeInfo) infos[i];
270:
271:                    if (!validTypes.contains(ftInfo)) {
272:                        File schemaFile = ftInfo.getSchemaFile();
273:
274:                        try {
275:                            //Hack here, schemaFile should not be null, but it is
276:                            //when a fType is first created, since we only add the 
277:                            //schemaFile param to dto on a load.  This should be
278:                            //fixed, maybe even have the schema file persist, or at
279:                            //the very least be present right after creation.
280:                            if ((schemaFile != null) && schemaFile.exists()
281:                                    && schemaFile.canRead()) {
282:                                generatedType = writeFile(schemaFile);
283:                            } else {
284:                                FeatureType ft2 = ftInfo.getFeatureType();
285:                                String gType2 = generateFromSchema(ft2);
286:
287:                                if ((gType2 != null) && (gType2 != "")) {
288:                                    generatedType = gType2;
289:                                }
290:                            }
291:                        } catch (IOException e) {
292:                            generatedType = "";
293:                        }
294:
295:                        if (!generatedType.equals("")) {
296:                            tempResponse = tempResponse + generatedType;
297:                            validTypes.add(ftInfo);
298:                        }
299:                    }
300:                }
301:
302:                // Loop through requested tables again to add elements
303:                // NOT VERY EFFICIENT - PERHAPS THE MYSQL ABSTRACTION CAN FIX THIS;
304:                //  STORE IN HASH?
305:                for (Iterator i = validTypes.iterator(); i.hasNext();) {
306:                    // Print element representation of table
307:                    tempResponse = tempResponse
308:                            + printElement((FeatureTypeInfo) i.next());
309:                }
310:
311:                tempResponse = tempResponse + "\n\n";
312:
313:                return tempResponse;
314:            }
315:
316:            /**
317:             * Transforms a FeatureTypeInfo into gml, with no headers.
318:             *
319:             * @param schema the schema to transform.
320:             *
321:             * @return DOCUMENT ME!
322:             *
323:             *  @task REVISIT: when this class changes to writing directly to out this
324:             *       can just take a writer and write directly to it.
325:             */
326:            private String generateFromSchema(FeatureType schema)
327:                    throws IOException {
328:                try {
329:                    StringWriter writer = new StringWriter();
330:                    FeatureTypeTransformer t = new FeatureTypeTransformer();
331:                    t.setIndentation(4);
332:                    t.setOmitXMLDeclaration(true);
333:                    t.transform(schema, writer);
334:
335:                    return writer.getBuffer().toString();
336:                } catch (TransformerException te) {
337:                    LOGGER.log(Level.WARNING,
338:                            "Error generating schema from feature type", te);
339:                    throw (IOException) new IOException(
340:                            "problem transforming type").initCause(te);
341:                }
342:            }
343:
344:            /**
345:             * Internal method to print XML element information for table.
346:             *
347:             * @param type The table name.
348:             *
349:             * @return The element part of the response.
350:             */
351:            private static String printElement(FeatureTypeInfo type) {
352:                return "\n  <xs:element name=\"" + type.getTypeName()
353:                        + "\" type=\"" + type.getNameSpace().getPrefix() + ":"
354:                        + type.getSchemaName()
355:                        + "\" substitutionGroup=\"gml:_Feature\"/>";
356:            }
357:
358:            /**
359:             * Adds a feature type object to the final output buffer
360:             *
361:             * @param inputFileName The name of the feature type.
362:             *
363:             * @return The string representation of the file containing the schema.
364:             *
365:             * @throws WFSException For io problems reading the file.
366:             */
367:            public String writeFile(File inputFile) throws IOException {
368:                LOGGER.finest("writing file " + inputFile);
369:
370:                String finalOutput = new String();
371:
372:                try {
373:                    // File inputFile = new File(inputFileName);
374:                    FileInputStream inputStream = new FileInputStream(inputFile);
375:                    byte[] fileBuffer = new byte[inputStream.available()];
376:                    int bytesRead;
377:
378:                    while ((bytesRead = inputStream.read(fileBuffer)) != -1) {
379:                        String tempOutput = new String(fileBuffer);
380:                        finalOutput = finalOutput + tempOutput;
381:                    }
382:                } catch (IOException e) {
383:                    //REVISIT: should things fail if there are featureTypes that
384:                    //don't have schemas in the right place?  Because as it is now
385:                    //a describe all will choke if there is one ft with no schema.xml
386:                    throw (IOException) new IOException(
387:                            "problem writing featureType information "
388:                                    + " from " + inputFile).initCause(e);
389:                }
390:
391:                return finalOutput;
392:            }
393:
394:            /**
395:             * Checks that the collection of featureTypeNames all have the same prefix.
396:             * Used to determine if their schemas are all in the same namespace or if
397:             * imports need to be done.
398:             *
399:             * @param  infos list of feature type info objects..
400:             *
401:             * @return true if all the types in the collection have the same prefix.
402:             *
403:             */
404:            public boolean allSameType(FeatureTypeInfo[] infos) {
405:                boolean sameType = true;
406:
407:                if (infos.length == 0) {
408:                    return false;
409:                }
410:
411:                FeatureTypeInfo first = infos[0];
412:
413:                for (int i = 0; i < infos.length; i++) {
414:                    FeatureTypeInfo ftInfo = infos[i];
415:
416:                    if (!first.getNameSpace().equals(ftInfo.getNameSpace())) {
417:                        return false;
418:                    }
419:                }
420:
421:                return sameType;
422:            }
423:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.