Source Code Cross Referenced for WMSCapsTransformer.java in  » GIS » GeoServer » org » vfny » geoserver » wms » responses » helpers » 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.vfny.geoserver.wms.responses.helpers 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
0002:         * This code is licensed under the GPL 2.0 license, availible at the root
0003:         * application directory.
0004:         */
0005:        package org.vfny.geoserver.wms.responses.helpers;
0006:
0007:        import java.io.IOException;
0008:        import java.util.ArrayList;
0009:        import java.util.Arrays;
0010:        import java.util.Collection;
0011:        import java.util.Iterator;
0012:        import java.util.List;
0013:        import java.util.Map;
0014:        import java.util.Set;
0015:        import java.util.logging.Level;
0016:        import java.util.logging.Logger;
0017:
0018:        import javax.xml.transform.OutputKeys;
0019:        import javax.xml.transform.Transformer;
0020:        import javax.xml.transform.TransformerException;
0021:
0022:        import org.apache.xalan.transformer.TransformerIdentityImpl;
0023:        import org.geoserver.ows.util.RequestUtils;
0024:        import org.geoserver.platform.GeoServerExtensions;
0025:        import org.geotools.geometry.GeneralEnvelope;
0026:        import org.geotools.referencing.CRS;
0027:        import org.geotools.resources.CRSUtilities;
0028:        import org.geotools.styling.Style;
0029:        import org.geotools.xml.transform.TransformerBase;
0030:        import org.geotools.xml.transform.Translator;
0031:        import org.opengis.referencing.FactoryException;
0032:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0033:        import org.opengis.referencing.operation.MathTransform;
0034:        import org.opengis.referencing.operation.TransformException;
0035:        import org.springframework.context.ApplicationContext;
0036:        import org.vfny.geoserver.global.CoverageInfo;
0037:        import org.vfny.geoserver.global.CoverageInfoLabelComparator;
0038:        import org.vfny.geoserver.global.Data;
0039:        import org.vfny.geoserver.global.FeatureTypeInfo;
0040:        import org.vfny.geoserver.global.FeatureTypeInfoTitleComparator;
0041:        import org.vfny.geoserver.global.GeoServer;
0042:        import org.vfny.geoserver.global.LegendURL;
0043:        import org.vfny.geoserver.global.MapLayerInfo;
0044:        import org.vfny.geoserver.global.MetaDataLink;
0045:        import org.vfny.geoserver.global.WMS;
0046:        import org.vfny.geoserver.util.requests.CapabilitiesRequest;
0047:        import org.vfny.geoserver.wms.WmsException;
0048:        import org.vfny.geoserver.wms.requests.GetLegendGraphicRequest;
0049:        import org.vfny.geoserver.wms.responses.DescribeLayerResponse;
0050:        import org.vfny.geoserver.wms.responses.GetFeatureInfoResponse;
0051:        import org.vfny.geoserver.wms.responses.GetLegendGraphicResponse;
0052:        import org.xml.sax.ContentHandler;
0053:        import org.xml.sax.helpers.AttributesImpl;
0054:        import java.util.Collections;
0055:
0056:        import com.vividsolutions.jts.geom.Envelope;
0057:
0058:        /**
0059:         * Geotools xml framework based encoder for a Capabilities WMS 1.1.1 document.
0060:         *
0061:         * @author Gabriel Roldan, Axios Engineering
0062:         * @version $Id
0063:         */
0064:        public class WMSCapsTransformer extends TransformerBase {
0065:            /** fixed MIME type for the returned capabilities document */
0066:            public static final String WMS_CAPS_MIME = "application/vnd.ogc.wms_xml";
0067:
0068:            /** DOCUMENT ME! */
0069:            private String baseUrl;
0070:            private Set formats;
0071:            private ApplicationContext applicationContext;
0072:
0073:            /**
0074:             * Creates a new WMSCapsTransformer object.
0075:             *
0076:             * @param baseUrl
0077:             *            needed to get the schema base URL
0078:             * @param formats
0079:             * @param applicationContext
0080:             *
0081:             * @throws NullPointerException
0082:             *             if <code>schemaBaseUrl</code> is null;
0083:             */
0084:            public WMSCapsTransformer(String baseUrl, Set formats,
0085:                    ApplicationContext applicationContext) {
0086:                super ();
0087:                this .formats = formats;
0088:
0089:                if (baseUrl == null) {
0090:                    throw new NullPointerException();
0091:                }
0092:
0093:                this .baseUrl = baseUrl;
0094:                this .setNamespaceDeclarationEnabled(false);
0095:                this .applicationContext = applicationContext;
0096:            }
0097:
0098:            /**
0099:             * DOCUMENT ME!
0100:             *
0101:             * @param handler
0102:             *            DOCUMENT ME!
0103:             *
0104:             * @return DOCUMENT ME!
0105:             */
0106:            public Translator createTranslator(ContentHandler handler) {
0107:                return new CapabilitiesTranslator(handler, formats,
0108:                        applicationContext);
0109:            }
0110:
0111:            /**
0112:             * Gets the <code>Transformer</code> created by the overriden method in
0113:             * the superclass and adds it the system DOCTYPE token pointing to the
0114:             * Capabilities DTD on this server instance.
0115:             *
0116:             * <p>
0117:             * The DTD is set at the fixed location given by the
0118:             * <code>schemaBaseUrl</code> passed to the constructor <code>+
0119:             * "wms/1.1.1/WMS_MS_Capabilities.dtd</code>.
0120:             * </p>
0121:             *
0122:             * @return a Transformer propoerly configured to produce DescribeLayer
0123:             *         responses.
0124:             *
0125:             * @throws TransformerException
0126:             *             if it is thrown by <code>super.createTransformer()</code>
0127:             */
0128:            public Transformer createTransformer() throws TransformerException {
0129:                Transformer transformer = super .createTransformer();
0130:                GeoServer gs = (GeoServer) GeoServerExtensions.extensions(
0131:                        GeoServer.class, applicationContext).get(0);
0132:                String dtdUrl = RequestUtils.proxifiedBaseURL(this .baseUrl, gs
0133:                        .getProxyBaseUrl())
0134:                        + "schemas/wms/1.1.1/WMS_MS_Capabilities.dtd"; // DJB: fixed this to
0135:                // point to correct
0136:                // location
0137:
0138:                transformer
0139:                        .setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, dtdUrl);
0140:
0141:                return transformer;
0142:            }
0143:
0144:            /**
0145:             * DOCUMENT ME!
0146:             *
0147:             * @author Gabriel Roldan, Axios Engineering
0148:             * @version $Id
0149:             */
0150:            private static class CapabilitiesTranslator extends
0151:                    TranslatorSupport {
0152:                /** DOCUMENT ME! */
0153:                private static final Logger LOGGER = org.geotools.util.logging.Logging
0154:                        .getLogger(CapabilitiesTranslator.class.getPackage()
0155:                                .getName());
0156:
0157:                /** DOCUMENT ME! */
0158:                private static final String EPSG = "EPSG:";
0159:
0160:                /** DOCUMENT ME! */
0161:                private static AttributesImpl wmsVersion = new AttributesImpl();
0162:
0163:                /** DOCUMENT ME! */
0164:                private static final String XLINK_NS = "http://www.w3.org/1999/xlink";
0165:
0166:                static {
0167:                    wmsVersion.addAttribute("", "version", "version", "",
0168:                            "1.1.1");
0169:                }
0170:
0171:                /**
0172:                 * The request from wich all the information needed to produce the
0173:                 * capabilities document can be obtained
0174:                 */
0175:                private CapabilitiesRequest request;
0176:                private Set formats;
0177:                private ApplicationContext applicationContext;
0178:
0179:                /**
0180:                 * Creates a new CapabilitiesTranslator object.
0181:                 *
0182:                 * @param handler
0183:                 *            content handler to send sax events to.
0184:                 */
0185:                public CapabilitiesTranslator(ContentHandler handler,
0186:                        Set formats, ApplicationContext applicationContext) {
0187:                    super (handler, null, null);
0188:                    this .formats = formats;
0189:                    this .applicationContext = applicationContext;
0190:                }
0191:
0192:                /**
0193:                 * DOCUMENT ME!
0194:                 *
0195:                 * @param o
0196:                 *            the <code>CapabilitiesRequest</code>
0197:                 *
0198:                 * @throws IllegalArgumentException
0199:                 *             DOCUMENT ME!
0200:                 */
0201:                public void encode(Object o) throws IllegalArgumentException {
0202:                    if (!(o instanceof  CapabilitiesRequest)) {
0203:                        throw new IllegalArgumentException();
0204:                    }
0205:
0206:                    this .request = (CapabilitiesRequest) o;
0207:
0208:                    if (LOGGER.isLoggable(Level.FINE)) {
0209:                        LOGGER.fine(new StringBuffer(
0210:                                "producing a capabilities document for ")
0211:                                .append(request).toString());
0212:                    }
0213:
0214:                    WMS wms = (WMS) request.getServiceRef().getServiceRef();
0215:                    AttributesImpl rootAtts = new AttributesImpl(wmsVersion);
0216:                    rootAtts.addAttribute("", "updateSequence",
0217:                            "updateSequence", "", wms.getGeoServer()
0218:                                    .getUpdateSequence()
0219:                                    + "");
0220:                    start("WMT_MS_Capabilities", rootAtts);
0221:                    handleService();
0222:                    handleCapability();
0223:                    end("WMT_MS_Capabilities");
0224:                }
0225:
0226:                /**
0227:                 * Encodes the service metadata section of a WMS capabilities document.
0228:                 */
0229:                private void handleService() {
0230:                    WMS wms = (WMS) request.getServiceRef().getServiceRef();
0231:                    start("Service");
0232:
0233:                    element("Name", "OGC:WMS");
0234:                    element("Title", wms.getTitle());
0235:                    element("Abstract", wms.getAbstract());
0236:
0237:                    handleKeywordList(wms.getKeywords());
0238:
0239:                    AttributesImpl orAtts = new AttributesImpl();
0240:                    orAtts.addAttribute("", "xmlns:xlink", "xmlns:xlink", "",
0241:                            XLINK_NS);
0242:                    orAtts.addAttribute(XLINK_NS, "xlink:type", "xlink:type",
0243:                            "", "simple");
0244:                    orAtts.addAttribute("", "xlink:href", "xlink:href", "",
0245:                            RequestUtils.proxifiedBaseURL(request.getBaseUrl(),
0246:                                    wms.getGeoServer().getProxyBaseUrl())
0247:                                    + "wms");
0248:                    element("OnlineResource", null, orAtts);
0249:
0250:                    handleContactInfo(wms.getGeoServer());
0251:
0252:                    element("Fees", wms.getFees());
0253:                    element("AccessConstraints", wms.getAccessConstraints());
0254:                    end("Service");
0255:                }
0256:
0257:                /**
0258:                 * Encodes contact information in the WMS capabilities document
0259:                 * @param geoServer
0260:                 */
0261:                public void handleContactInfo(GeoServer geoServer) {
0262:                    start("ContactInformation");
0263:
0264:                    start("ContactPersonPrimary");
0265:                    element("ContactPerson", geoServer.getContactPerson());
0266:                    element("ContactOrganization", geoServer
0267:                            .getContactOrganization());
0268:                    end("ContactPersonPrimary");
0269:
0270:                    element("ContactPosition", geoServer.getContactPosition());
0271:
0272:                    start("ContactAddress");
0273:                    element("AddressType", geoServer.getAddressType());
0274:                    element("Address", geoServer.getAddress());
0275:                    element("City", geoServer.getAddressCity());
0276:                    element("StateOrProvince", geoServer.getAddressState());
0277:                    element("PostCode", geoServer.getAddressPostalCode());
0278:                    element("Country", geoServer.getAddressCountry());
0279:                    end("ContactAddress");
0280:
0281:                    element("ContactVoiceTelephone", geoServer
0282:                            .getContactVoice());
0283:                    element("ContactFacsimileTelephone", geoServer
0284:                            .getContactFacsimile());
0285:                    element("ContactElectronicMailAddress", geoServer
0286:                            .getContactEmail());
0287:
0288:                    end("ContactInformation");
0289:                }
0290:
0291:                /**
0292:                 * Turns the keyword list to XML
0293:                 *
0294:                 * @param keywords
0295:                 */
0296:                private void handleKeywordList(List keywords) {
0297:                    start("KeywordList");
0298:
0299:                    if (keywords != null) {
0300:                        for (Iterator it = keywords.iterator(); it.hasNext();) {
0301:                            element("Keyword", String.valueOf(it.next()));
0302:                        }
0303:                    }
0304:
0305:                    end("KeywordList");
0306:                }
0307:
0308:                /**
0309:                 * Turns the metadata URL list to XML
0310:                 *
0311:                 * @param keywords
0312:                 */
0313:                private void handleMetadataList(List metadataURLs) {
0314:                    if (metadataURLs == null) {
0315:                        return;
0316:                    }
0317:
0318:                    for (Iterator it = metadataURLs.iterator(); it.hasNext();) {
0319:                        MetaDataLink link = (MetaDataLink) it.next();
0320:
0321:                        AttributesImpl lnkAtts = new AttributesImpl();
0322:                        lnkAtts.addAttribute("", "type", "type", "", link
0323:                                .getMetadataType());
0324:                        start("MetadataURL", lnkAtts);
0325:
0326:                        element("Format", link.getType());
0327:
0328:                        AttributesImpl orAtts = new AttributesImpl();
0329:                        orAtts.addAttribute("", "xmlns:xlink", "xmlns:xlink",
0330:                                "", XLINK_NS);
0331:                        orAtts.addAttribute(XLINK_NS, "xlink:type",
0332:                                "xlink:type", "", "simple");
0333:                        orAtts.addAttribute("", "xlink:href", "xlink:href", "",
0334:                                link.getContent());
0335:                        element("OnlineResource", null, orAtts);
0336:
0337:                        end("MetadataURL");
0338:                    }
0339:                }
0340:
0341:                /**
0342:                 * Encodes the capabilities metadata section of a WMS capabilities
0343:                 * document
0344:                 */
0345:                private void handleCapability() {
0346:                    start("Capability");
0347:                    handleRequest();
0348:                    handleException();
0349:                    handleSLD();
0350:                    handleLayers();
0351:                    end("Capability");
0352:                }
0353:
0354:                /**
0355:                 * DOCUMENT ME!
0356:                 */
0357:                private void handleRequest() {
0358:                    start("Request");
0359:
0360:                    start("GetCapabilities");
0361:                    element("Format", WMS_CAPS_MIME);
0362:
0363:                    String serviceUrl = RequestUtils.proxifiedBaseURL(request
0364:                            .getBaseUrl(), request.getServiceRef()
0365:                            .getGeoServer().getProxyBaseUrl())
0366:                            + "wms?SERVICE=WMS&";
0367:
0368:                    handleDcpType(serviceUrl, serviceUrl);
0369:                    end("GetCapabilities");
0370:
0371:                    start("GetMap");
0372:
0373:                    List sortedFormats = new ArrayList(formats);
0374:                    Collections.sort(sortedFormats);
0375:                    // this is a hack necessary to make cite tests pass: we need an output format
0376:                    // that is equal to the mime type as the first one....
0377:                    if (sortedFormats.contains("image/png")) {
0378:                        sortedFormats.remove("image/png");
0379:                        sortedFormats.add(0, "image/png");
0380:                    }
0381:                    for (Iterator it = sortedFormats.iterator(); it.hasNext();) {
0382:                        element("Format", String.valueOf(it.next()));
0383:                    }
0384:
0385:                    handleDcpType(serviceUrl, null);
0386:                    end("GetMap");
0387:
0388:                    start("GetFeatureInfo");
0389:
0390:                    for (Iterator it = GetFeatureInfoResponse.getFormats()
0391:                            .iterator(); it.hasNext();) {
0392:                        element("Format", String.valueOf(it.next()));
0393:                    }
0394:
0395:                    handleDcpType(serviceUrl, serviceUrl);
0396:                    end("GetFeatureInfo");
0397:
0398:                    start("DescribeLayer");
0399:                    element("Format", DescribeLayerResponse.DESCLAYER_MIME_TYPE);
0400:                    handleDcpType(serviceUrl, null);
0401:                    end("DescribeLayer");
0402:
0403:                    start("GetLegendGraphic");
0404:
0405:                    for (Iterator it = GetLegendGraphicResponse.getFormats(
0406:                            applicationContext).iterator(); it.hasNext();) {
0407:                        element("Format", String.valueOf(it.next()));
0408:                    }
0409:
0410:                    handleDcpType(serviceUrl, null);
0411:                    end("GetLegendGraphic");
0412:
0413:                    end("Request");
0414:                }
0415:
0416:                /**
0417:                 * Encodes a <code>DCPType</code> fragment for HTTP GET and POST
0418:                 * methods.
0419:                 *
0420:                 * @param getUrl the URL of the onlineresource for HTTP GET method
0421:                 *        requests
0422:                 * @param postUrl the URL of the onlineresource for HTTP POST method
0423:                 *        requests
0424:                 */
0425:                private void handleDcpType(String getUrl, String postUrl) {
0426:                    AttributesImpl orAtts = new AttributesImpl();
0427:                    orAtts.addAttribute("", "xmlns:xlink", "xmlns:xlink", "",
0428:                            XLINK_NS);
0429:                    orAtts.addAttribute("", "xlink:type", "xlink:type", "",
0430:                            "simple");
0431:                    orAtts.addAttribute("", "xlink:href", "xlink:href", "",
0432:                            getUrl);
0433:                    start("DCPType");
0434:                    start("HTTP");
0435:
0436:                    if (getUrl != null) {
0437:                        start("Get");
0438:                        element("OnlineResource", null, orAtts);
0439:                        end("Get");
0440:                    }
0441:
0442:                    if (postUrl != null) {
0443:                        orAtts.setAttribute(2, "", "xlink:href", "xlink:href",
0444:                                "", postUrl);
0445:                        start("Post");
0446:                        element("OnlineResource", null, orAtts);
0447:                        end("Post");
0448:                    }
0449:
0450:                    end("HTTP");
0451:                    end("DCPType");
0452:                }
0453:
0454:                /**
0455:                 * DOCUMENT ME!
0456:                 */
0457:                private void handleException() {
0458:                    start("Exception");
0459:
0460:                    WMS wms = (WMS) request.getServiceRef().getServiceRef();
0461:                    Iterator it = Arrays.asList(wms.getExceptionFormats())
0462:                            .iterator();
0463:
0464:                    while (it.hasNext()) {
0465:                        element("Format", String.valueOf(it.next()));
0466:                    }
0467:
0468:                    end("Exception");
0469:                }
0470:
0471:                /**
0472:                 * DOCUMENT ME!
0473:                 */
0474:                private void handleSLD() {
0475:                    AttributesImpl sldAtts = new AttributesImpl();
0476:                    WMS config = (WMS) request.getServiceRef().getServiceRef();
0477:                    String supportsSLD = config.supportsSLD() ? "1" : "0";
0478:                    String supportsUserLayer = config.supportsUserLayer() ? "1"
0479:                            : "0";
0480:                    String supportsUserStyle = config.supportsUserStyle() ? "1"
0481:                            : "0";
0482:                    String supportsRemoteWFS = config.supportsRemoteWFS() ? "1"
0483:                            : "0";
0484:                    sldAtts.addAttribute("", "SupportSLD", "SupportSLD", "",
0485:                            supportsSLD);
0486:                    sldAtts.addAttribute("", "UserLayer", "UserLayer", "",
0487:                            supportsUserLayer);
0488:                    sldAtts.addAttribute("", "UserStyle", "UserStyle", "",
0489:                            supportsUserStyle);
0490:                    sldAtts.addAttribute("", "RemoteWFS", "RemoteWFS", "",
0491:                            supportsRemoteWFS);
0492:
0493:                    start("UserDefinedSymbolization", sldAtts);
0494:                    //          djb: this was removed, even though they are correct - the CITE tests have an incorrect DTD
0495:                    //       element("SupportedSLDVersion","1.0.0");  //djb: added that we support this.  We support partial 1.1
0496:                    end("UserDefinedSymbolization");
0497:
0498:                    //element("UserDefinedSymbolization", null, sldAtts);
0499:                }
0500:
0501:                /**
0502:                 * Handles the encoding of the layers elements.
0503:                 *
0504:                 * <p>
0505:                 * This method does a search over the SRS of all the layers to see if
0506:                 * there are at least a common one, as needed by the spec: "<i>The root
0507:                 * Layer element shall include a sequence of zero or more &lt;SRS&gt;
0508:                 * elements listing all SRSes that are common to all subsidiary layers.
0509:                 * Use a single SRS element with empty content (like so:
0510:                 * "&lt;SRS&gt;&lt;/SRS&gt;") if there is no common SRS."</i>
0511:                 * </p>
0512:                 *
0513:                 * <p>
0514:                 * By the other hand, this search is also used to collecto the whole
0515:                 * latlon bbox, as stated by the spec: <i>"The bounding box metadata in
0516:                 * Capabilities XML specify the minimum enclosing rectangle for the
0517:                 * layer as a whole."</i>
0518:                 * </p>
0519:                 *
0520:                 * @task TODO: manage this differently when we have the layer list of
0521:                 *       the WMS service decoupled from the feature types configured for
0522:                 *       the server instance. (This involves nested layers,
0523:                 *       gridcoverages, etc)
0524:                 */
0525:                private void handleLayers() {
0526:                    WMS wms = (WMS) request.getServiceRef().getServiceRef();
0527:                    start("Layer");
0528:
0529:                    Data catalog = wms.getData();
0530:                    Collection ftypes = catalog.getFeatureTypeInfos().values();
0531:                    Collection coverages = catalog.getCoverageInfos().values();
0532:
0533:                    element("Title", wms.getTitle());
0534:                    element("Abstract", wms.getAbstract());
0535:
0536:                    handleRootSRSAndBbox(ftypes, MapLayerInfo.TYPE_VECTOR);
0537:
0538:                    // now encode each layer individually
0539:                    LayerTree featuresLayerTree = new LayerTree(ftypes);
0540:                    handleFeaturesTree(featuresLayerTree);
0541:
0542:                    LayerTree coveragesLayerTree = new LayerTree(coverages);
0543:                    handleCoveragesTree(coveragesLayerTree);
0544:
0545:                    try {
0546:                        handleLayerGroups(wms.getBaseMapLayers(), wms
0547:                                .getBaseMapStyles(), wms.getBaseMapEnvelopes());
0548:                    } catch (FactoryException e) {
0549:                        throw new RuntimeException(
0550:                                "Can't obtain Envelope of Layer-Groups: "
0551:                                        + e.getMessage(), e);
0552:                    } catch (TransformException e) {
0553:                        throw new RuntimeException(
0554:                                "Can't obtain Envelope of Layer-Groups: "
0555:                                        + e.getMessage(), e);
0556:                    }
0557:
0558:                    end("Layer");
0559:                }
0560:
0561:                /**
0562:                 * Called from <code>handleLayers()</code>, does the first
0563:                 * iteration over the available featuretypes to look for common SRS's
0564:                 * and summarize their LatLonBBox'es, to state at the root layer.<p>NOTE:
0565:                 * by now we just have "layer.getSRS()", so the search is done against
0566:                 * this only SRS.</p>
0567:                 *
0568:                 * @param ftypes DOCUMENT ME!
0569:                 * @param TYPE DOCUMENT ME!
0570:                 *
0571:                 * @throws RuntimeException DOCUMENT ME!
0572:                 *
0573:                 * @task TODO: figure out how to incorporate multiple SRS using the
0574:                 *       reprojection facilities from gt2
0575:                 */
0576:                private void handleRootSRSAndBbox(Collection ftypes, int TYPE) {
0577:                    String commonSRS = "";
0578:                    boolean isCommonSRS = true;
0579:                    Envelope latlonBbox = new Envelope();
0580:                    Envelope layerBbox = null;
0581:
0582:                    if (LOGGER.isLoggable(Level.FINER)) {
0583:                        LOGGER
0584:                                .finer("Collecting summarized latlonbbox and common SRS...");
0585:                    }
0586:
0587:                    if (TYPE == MapLayerInfo.TYPE_VECTOR) {
0588:                        FeatureTypeInfo layer;
0589:
0590:                        for (Iterator it = ftypes.iterator(); it.hasNext();) {
0591:                            layer = (FeatureTypeInfo) it.next();
0592:
0593:                            if (layer.isEnabled()) {
0594:                                try {
0595:                                    layerBbox = layer.getLatLongBoundingBox();
0596:                                } catch (IOException e) {
0597:                                    throw new RuntimeException(
0598:                                            "Can't obtain latLonBBox of "
0599:                                                    + layer.getName() + ": "
0600:                                                    + e.getMessage(), e);
0601:                                }
0602:
0603:                                latlonBbox.expandToInclude(layerBbox);
0604:
0605:                                String layerSRS = layer.getSRS();
0606:
0607:                                if ("".equals(commonSRS)) {
0608:                                    commonSRS = layerSRS;
0609:                                } else if (!commonSRS.equals(layerSRS)) {
0610:                                    isCommonSRS = false;
0611:                                }
0612:                            }
0613:                        }
0614:
0615:                        if (isCommonSRS) {
0616:                            commonSRS = EPSG + commonSRS;
0617:                            LOGGER.fine("Common SRS is " + commonSRS);
0618:                        } else {
0619:                            commonSRS = "";
0620:                            LOGGER
0621:                                    .fine("No common SRS, don't forget to incorporate reprojection support...");
0622:                        }
0623:
0624:                        if (!(commonSRS.equals(""))) {
0625:                            comment("common SRS:");
0626:                            element("SRS", commonSRS);
0627:                        }
0628:
0629:                        // okay - we've sent out the commonSRS, if it exists.
0630:                        comment("All supported EPSG projections:");
0631:
0632:                        try {
0633:                            Set s = CRS.getSupportedCodes("EPSG");
0634:                            Iterator it = s.iterator();
0635:                            String currentSRS;
0636:
0637:                            while (it.hasNext()) {
0638:                                // do not output srs if it was output as common srs
0639:                                // note, if commonSRS is "", this will not match
0640:                                currentSRS = it.next().toString();
0641:
0642:                                if (!currentSRS.equals(commonSRS)) {
0643:                                    element("SRS", EPSG + currentSRS);
0644:                                }
0645:                            }
0646:                        } catch (Exception e) {
0647:                            if (LOGGER.isLoggable(Level.WARNING)) {
0648:                                LOGGER.log(Level.WARNING, e
0649:                                        .getLocalizedMessage(), e);
0650:                            }
0651:                        }
0652:
0653:                        if (LOGGER.isLoggable(Level.FINE)) {
0654:                            LOGGER.fine("Summarized LatLonBBox is "
0655:                                    + latlonBbox);
0656:                        }
0657:
0658:                        handleLatLonBBox(latlonBbox);
0659:                    } else if (TYPE == MapLayerInfo.TYPE_RASTER) {
0660:                        CoverageInfo layer;
0661:
0662:                        for (Iterator it = ftypes.iterator(); it.hasNext();) {
0663:                            layer = (CoverageInfo) it.next();
0664:
0665:                            if (layer.isEnabled()) {
0666:                                final GeneralEnvelope bbox = layer
0667:                                        .getWGS84LonLatEnvelope();
0668:                                layerBbox = new Envelope(bbox.getLowerCorner()
0669:                                        .getOrdinate(0), bbox.getUpperCorner()
0670:                                        .getOrdinate(0), bbox.getLowerCorner()
0671:                                        .getOrdinate(1), bbox.getUpperCorner()
0672:                                        .getOrdinate(1));
0673:
0674:                                latlonBbox.expandToInclude(layerBbox);
0675:
0676:                                String layerSRS = layer.getSrsName();
0677:
0678:                                if ("".equals(commonSRS)) {
0679:                                    commonSRS = layerSRS;
0680:                                } else if (!commonSRS.equals(layerSRS)) {
0681:                                    isCommonSRS = false;
0682:                                }
0683:                            }
0684:                        }
0685:
0686:                        if (isCommonSRS) {
0687:                            // commonSRS = EPSG + commonSRS;
0688:                            if (LOGGER.isLoggable(Level.FINE)) {
0689:                                LOGGER.fine(new StringBuffer("Common SRS is ")
0690:                                        .append(commonSRS).toString());
0691:                            }
0692:                        } else {
0693:                            commonSRS = "";
0694:
0695:                            if (LOGGER.isLoggable(Level.FINE)) {
0696:                                LOGGER
0697:                                        .fine("No common SRS, don't forget to incorporate reprojection support...");
0698:                            }
0699:                        }
0700:
0701:                        if (!(commonSRS.equals(""))) {
0702:                            comment("common SRS:");
0703:                            element("SRS", commonSRS);
0704:                        }
0705:
0706:                        // okay - we've sent out the commonSRS, if it exists.
0707:                        comment("All supported EPSG projections:");
0708:
0709:                        try {
0710:                            String currentSRS;
0711:                            ArrayList SRSs = new ArrayList(ftypes.size());
0712:
0713:                            for (Iterator it = ftypes.iterator(); it.hasNext();) {
0714:                                layer = (CoverageInfo) it.next();
0715:
0716:                                if (layer.isEnabled()) {
0717:                                    List s = layer.getRequestCRSs();
0718:                                    Iterator it_1 = s.iterator();
0719:
0720:                                    while (it_1.hasNext()) {
0721:                                        // do not output srs if it was output as common
0722:                                        // srs
0723:                                        // note, if commonSRS is "", this will not match
0724:                                        currentSRS = it_1.next().toString();
0725:
0726:                                        if (!currentSRS.equals(commonSRS)
0727:                                                && !SRSs.contains(currentSRS)) {
0728:                                            SRSs.add(currentSRS);
0729:                                            element("SRS", currentSRS);
0730:                                        }
0731:                                    }
0732:                                }
0733:                            }
0734:                        } catch (Exception e) {
0735:                            if (LOGGER.isLoggable(Level.WARNING)) {
0736:                                LOGGER.log(Level.WARNING, e
0737:                                        .getLocalizedMessage(), e);
0738:                            }
0739:                        }
0740:
0741:                        if (LOGGER.isLoggable(Level.FINE)) {
0742:                            LOGGER.fine("Summarized LatLonBBox is "
0743:                                    + latlonBbox);
0744:                        }
0745:
0746:                        handleLatLonBBox(latlonBbox);
0747:                    }
0748:                }
0749:
0750:                /**
0751:                 * @param featuresLayerTree
0752:                 */
0753:                private void handleFeaturesTree(LayerTree featuresLayerTree) {
0754:                    final List data = new ArrayList(featuresLayerTree.getData());
0755:                    final Collection childrens = featuresLayerTree
0756:                            .getChildrens();
0757:                    FeatureTypeInfo fLayer;
0758:
0759:                    Collections
0760:                            .sort(data, new FeatureTypeInfoTitleComparator());
0761:                    for (Iterator it = data.iterator(); it.hasNext();) {
0762:                        fLayer = (FeatureTypeInfo) it.next();
0763:
0764:                        try {
0765:                            if (fLayer.isEnabled() && !fLayer.isGeometryless()) {
0766:                                handleFeatureType(fLayer);
0767:                            }
0768:                        } catch (Exception e) {
0769:                            if (LOGGER.isLoggable(Level.WARNING)) {
0770:                                LOGGER.log(Level.WARNING, e
0771:                                        .getLocalizedMessage(), e);
0772:                            }
0773:                        }
0774:                    }
0775:
0776:                    LayerTree layerTree;
0777:
0778:                    for (Iterator it = childrens.iterator(); it.hasNext();) {
0779:                        layerTree = (LayerTree) it.next();
0780:                        start("Layer");
0781:                        element("Name", layerTree.getName());
0782:                        element("Title", layerTree.getName());
0783:                        handleFeaturesTree(layerTree);
0784:                        end("Layer");
0785:                    }
0786:                }
0787:
0788:                /**
0789:                 * Calls super.handleFeatureType to add common FeatureType content such
0790:                 * as Name, Title and LatLonBoundingBox, and then writes WMS specific
0791:                 * layer properties as Styles, Scale Hint, etc.
0792:                 *
0793:                 * @param ftype
0794:                 *            The featureType to write out.
0795:                 *
0796:                 * @throws RuntimeException
0797:                 *             DOCUMENT ME!
0798:                 *
0799:                 * @task TODO: write wms specific elements.
0800:                 */
0801:                protected void handleFeatureType(FeatureTypeInfo ftype) {
0802:                    // HACK: by now all our layers are queryable, since they reference
0803:                    // only featuretypes managed by this server
0804:                    AttributesImpl qatts = new AttributesImpl();
0805:                    qatts.addAttribute("", "queryable", "queryable", "", "1");
0806:                    start("Layer", qatts);
0807:                    element("Name", ftype.getName());
0808:                    element("Title", ftype.getTitle());
0809:                    element("Abstract", ftype.getAbstract());
0810:
0811:                    handleKeywordList(ftype.getKeywords());
0812:
0813:                    /**
0814:                     * @task REVISIT: should getSRS() return the full URL? no - the spec
0815:                     *       says it should be a set of <SRS>EPSG:#</SRS>...
0816:                     */
0817:                    element("SRS", EPSG + ftype.getSRS());
0818:
0819:                    // DJB: I want to be nice to the people reading the capabilities
0820:                    // file - I'm going to get the
0821:                    // human readable name and stick it in the capabilities file
0822:                    // NOTE: this isnt well done because "comment()" isnt in the
0823:                    // ContentHandler interface...
0824:                    try {
0825:                        CoordinateReferenceSystem crs = CRS.decode(EPSG
0826:                                + ftype.getSRS());
0827:                        String desc = "WKT definition of this CRS:\n" + crs;
0828:                        comment(desc);
0829:                    } catch (Exception e) {
0830:                        if (LOGGER.isLoggable(Level.WARNING)) {
0831:                            LOGGER.log(Level.WARNING, e.getLocalizedMessage(),
0832:                                    e);
0833:                        }
0834:                    }
0835:
0836:                    Envelope bbox = null;
0837:                    Envelope llbbox = null;
0838:
0839:                    try {
0840:                        bbox = ftype.getBoundingBox();
0841:                        llbbox = ftype.getLatLongBoundingBox();
0842:                    } catch (IOException ex) {
0843:                        throw new RuntimeException(
0844:                                "Can't obtain latLongBBox of "
0845:                                        + ftype.getName() + ": "
0846:                                        + ex.getMessage(), ex);
0847:                    }
0848:
0849:                    handleLatLonBBox(llbbox);
0850:                    handleBBox(bbox, EPSG + ftype.getSRS());
0851:                    // handle metadata URLs
0852:                    handleMetadataList(ftype.getMetadataLinks());
0853:
0854:                    // add the layer style
0855:                    start("Style");
0856:
0857:                    Style ftStyle = ftype.getDefaultStyle();
0858:                    element("Name", ftStyle.getName());
0859:                    element("Title", ftStyle.getTitle());
0860:                    element("Abstract", ftStyle.getAbstract());
0861:                    handleLegendURL(ftype);
0862:                    end("Style");
0863:
0864:                    final ArrayList styles = ftype.getStyles();
0865:                    Iterator s_IT = styles.iterator();
0866:
0867:                    while (s_IT.hasNext()) {
0868:                        ftStyle = (Style) s_IT.next();
0869:                        start("Style");
0870:                        element("Name", ftStyle.getName());
0871:                        element("Title", ftStyle.getTitle());
0872:                        element("Abstract", ftStyle.getAbstract());
0873:                        handleLegendURL(ftype);
0874:                        end("Style");
0875:                    }
0876:
0877:                    end("Layer");
0878:                }
0879:
0880:                /**
0881:                 * @param coveragesLayerTree
0882:                 */
0883:                private void handleCoveragesTree(LayerTree coveragesLayerTree) {
0884:                    final List data = new ArrayList(coveragesLayerTree
0885:                            .getData());
0886:                    final Collection childrens = coveragesLayerTree
0887:                            .getChildrens();
0888:                    CoverageInfo cLayer;
0889:
0890:                    Collections.sort(data, new CoverageInfoLabelComparator());
0891:                    for (Iterator it = data.iterator(); it.hasNext();) {
0892:                        cLayer = (CoverageInfo) it.next();
0893:
0894:                        if (cLayer.isEnabled()) {
0895:                            handleCoverage(cLayer);
0896:                        }
0897:                    }
0898:
0899:                    LayerTree layerTree;
0900:
0901:                    for (Iterator it = childrens.iterator(); it.hasNext();) {
0902:                        layerTree = (LayerTree) it.next();
0903:                        start("Layer");
0904:                        element("Name", layerTree.getName());
0905:                        element("Title", layerTree.getName());
0906:                        handleCoveragesTree(layerTree);
0907:                        end("Layer");
0908:                    }
0909:                }
0910:
0911:                protected void handleCoverage(CoverageInfo coverage) {
0912:                    // HACK: by now all our layers are queryable, since they reference
0913:                    // only featuretypes managed by this server
0914:                    AttributesImpl qatts = new AttributesImpl();
0915:                    qatts.addAttribute("", "queryable", "queryable", "", "1");
0916:                    // qatts.addAttribute("", "opaque", "opaque", "", "1");
0917:                    // qatts.addAttribute("", "cascaded", "cascaded", "", "1");
0918:                    start("Layer", qatts);
0919:                    element("Name", coverage.getName());
0920:                    element("Title", coverage.getLabel());
0921:                    element("Abstract", coverage.getDescription());
0922:
0923:                    handleKeywordList(coverage.getKeywords());
0924:
0925:                    String desc = "WKT definition of this CRS:\n"
0926:                            + coverage.getSrsWKT();
0927:                    comment(desc);
0928:
0929:                    String authority = coverage.getSrsName();
0930:
0931:                    /*CoordinateReferenceSystem crs = coverage.getCrs();
0932:                    if (crs != null && !crs.getIdentifiers().isEmpty()) {
0933:                            Identifier[] idents = (Identifier[]) crs.getIdentifiers()
0934:                                            .toArray(new Identifier[crs.getIdentifiers().size()]);
0935:                            authority = idents[0].toString();
0936:                    } else if (crs != null && crs instanceof DerivedCRS) {
0937:                            final CoordinateReferenceSystem baseCRS = ((DerivedCRS) crs)
0938:                                            .getBaseCRS();
0939:                            if (baseCRS != null && !baseCRS.getIdentifiers().isEmpty())
0940:                                    authority = ((Identifier[]) baseCRS.getIdentifiers()
0941:                                                    .toArray(
0942:                                                                    new Identifier[baseCRS.getIdentifiers()
0943:                                                                                    .size()]))[0].toString();
0944:                            else
0945:                                    authority = coverage.getNativeCRS();
0946:                    } else if (crs != null && crs instanceof ProjectedCRS) {
0947:                            final CoordinateReferenceSystem baseCRS = ((ProjectedCRS) crs)
0948:                                            .getBaseCRS();
0949:                            if (baseCRS != null && !baseCRS.getIdentifiers().isEmpty())
0950:                                    authority = ((Identifier[]) baseCRS.getIdentifiers()
0951:                                                    .toArray(
0952:                                                                    new Identifier[baseCRS.getIdentifiers()
0953:                                                                                    .size()]))[0].toString();
0954:                            else
0955:                                    authority = coverage.getNativeCRS();
0956:                    } else
0957:                            authority = coverage.getNativeCRS();*/
0958:                    element("SRS", authority);
0959:
0960:                    GeneralEnvelope bounds = null;
0961:                    GeneralEnvelope llBounds = null;
0962:
0963:                    // try {
0964:                    // We need LON/LAT Envelopes
0965:                    // TODO check for BBOX, maybe it should be expressed in original
0966:                    // CRS coords!!
0967:                    final GeneralEnvelope latLonEnvelope = coverage
0968:                            .getWGS84LonLatEnvelope();
0969:                    // final CoordinateReferenceSystem llCRS = latLonEnvelope
0970:                    // .getCoordinateReferenceSystem();
0971:                    bounds = coverage.getEnvelope();
0972:                    llBounds = latLonEnvelope;
0973:
0974:                    // bounds =
0975:                    // CoverageStoreUtils.adjustEnvelopeLongitudeFirst(llCRS,
0976:                    // coverage.getEnvelope());
0977:                    // llBounds =
0978:                    // CoverageStoreUtils.adjustEnvelopeLongitudeFirst(llCRS,
0979:                    // // latLonEnvelope);
0980:                    // } catch (MismatchedDimensionException e) {
0981:                    //	
0982:                    // } catch (IndexOutOfBoundsException e) {
0983:                    //			
0984:                    // }
0985:                    final Envelope bbox = new Envelope(bounds.getLowerCorner()
0986:                            .getOrdinate(0), bounds.getUpperCorner()
0987:                            .getOrdinate(0), bounds.getLowerCorner()
0988:                            .getOrdinate(1), bounds.getUpperCorner()
0989:                            .getOrdinate(1));
0990:
0991:                    final Envelope llBbox = new Envelope(llBounds
0992:                            .getLowerCorner().getOrdinate(0), llBounds
0993:                            .getUpperCorner().getOrdinate(0), llBounds
0994:                            .getLowerCorner().getOrdinate(1), llBounds
0995:                            .getUpperCorner().getOrdinate(1));
0996:
0997:                    handleLatLonBBox(llBbox);
0998:                    handleBBox(bbox, authority);
0999:
1000:                    // add the layer style
1001:                    start("Style");
1002:
1003:                    Style cvStyle = coverage.getDefaultStyle();
1004:                    element("Name", cvStyle.getName());
1005:                    element("Title", cvStyle.getTitle());
1006:                    element("Abstract", cvStyle.getAbstract());
1007:                    handleLegendURL(coverage);
1008:                    end("Style");
1009:
1010:                    final ArrayList styles = coverage.getStyles();
1011:                    Iterator s_IT = styles.iterator();
1012:
1013:                    while (s_IT.hasNext()) {
1014:                        cvStyle = (Style) s_IT.next();
1015:                        start("Style");
1016:                        element("Name", cvStyle.getName());
1017:                        element("Title", cvStyle.getTitle());
1018:                        element("Abstract", cvStyle.getAbstract());
1019:                        handleLegendURL(coverage);
1020:                        end("Style");
1021:                    }
1022:
1023:                    end("Layer");
1024:                }
1025:
1026:                protected void handleLayerGroups(Map baseMapLayers,
1027:                        Map baseMapStyles, Map baseMapEnvelopes)
1028:                        throws FactoryException, TransformException {
1029:                    if (baseMapLayers == null) {
1030:                        return;
1031:                    }
1032:
1033:                    List names = new ArrayList(baseMapLayers.keySet());
1034:                    Collections.sort(names);
1035:
1036:                    CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326");
1037:
1038:                    for (Iterator it = names.iterator(); it.hasNext();) {
1039:                        String layerName = (String) it.next();
1040:
1041:                        AttributesImpl qatts = new AttributesImpl();
1042:                        qatts.addAttribute("", "queryable", "queryable", "",
1043:                                "0");
1044:                        // qatts.addAttribute("", "opaque", "opaque", "", "1");
1045:                        // qatts.addAttribute("", "cascaded", "cascaded", "", "1");
1046:                        start("Layer", qatts);
1047:                        element("Name", layerName);
1048:                        element("Title", layerName);
1049:                        element("Abstract", "Layer-Group type layer: "
1050:                                + layerName);
1051:
1052:                        //handleKeywordList(...getKeywords());
1053:
1054:                        /*String desc = "WKT definition of this CRS:\n" + coverage.getSrsWKT();
1055:                        comment(desc);*/
1056:                        GeneralEnvelope bounds = (GeneralEnvelope) baseMapEnvelopes
1057:                                .get(layerName);
1058:                        GeneralEnvelope llBounds = null;
1059:
1060:                        String authority = bounds
1061:                                .getCoordinateReferenceSystem()
1062:                                .getIdentifiers().toArray()[0].toString();
1063:
1064:                        element("SRS", authority);
1065:
1066:                        if (CRSUtilities.equalsIgnoreMetadata(wgs84, bounds
1067:                                .getCoordinateReferenceSystem())) {
1068:                            llBounds = bounds;
1069:                        } else {
1070:                            try {
1071:                                final MathTransform srcCRStoWGS84 = CRS
1072:                                        .findMathTransform(
1073:                                                bounds
1074:                                                        .getCoordinateReferenceSystem(),
1075:                                                wgs84, true);
1076:                                final GeneralEnvelope latLonEnvelope = CRS
1077:                                        .transform(srcCRStoWGS84, bounds);
1078:                                latLonEnvelope
1079:                                        .setCoordinateReferenceSystem(wgs84);
1080:                                llBounds = latLonEnvelope;
1081:                            } catch (TransformException e) {
1082:                                throw new WmsException(
1083:                                        "Cannot transform envelope to WGS84 for layer group "
1084:                                                + layerName,
1085:                                        "TransformException", e);
1086:                            }
1087:                        }
1088:
1089:                        final Envelope bbox = new Envelope(bounds
1090:                                .getLowerCorner().getOrdinate(0), bounds
1091:                                .getUpperCorner().getOrdinate(0), bounds
1092:                                .getLowerCorner().getOrdinate(1), bounds
1093:                                .getUpperCorner().getOrdinate(1));
1094:
1095:                        final Envelope llBbox = new Envelope(llBounds
1096:                                .getLowerCorner().getOrdinate(0), llBounds
1097:                                .getUpperCorner().getOrdinate(0), llBounds
1098:                                .getLowerCorner().getOrdinate(1), llBounds
1099:                                .getUpperCorner().getOrdinate(1));
1100:
1101:                        handleLatLonBBox(llBbox);
1102:                        handleBBox(bbox, authority);
1103:
1104:                        // add the layer style
1105:                        start("Style");
1106:
1107:                        element("Name", layerName);
1108:                        element("Title", layerName);
1109:                        element("Abstract", "Layer-Group complex style");
1110:                        //handleLegendURL(...URL);
1111:                        end("Style");
1112:
1113:                        end("Layer");
1114:                    }
1115:                }
1116:
1117:                /**
1118:                 * Writes layer LegendURL pointing to the user supplied icon URL, if
1119:                 * any, or to the proper GetLegendGraphic operation if an URL was not
1120:                 * supplied by configuration file.
1121:                 *
1122:                 * <p>
1123:                 * It is common practice to supply a URL to a WMS accesible legend
1124:                 * graphic when it is difficult to create a dynamic legend for a layer.
1125:                 * </p>
1126:                 *
1127:                 * @param ft
1128:                 *            The FeatureTypeInfo that holds the legendURL to write out,
1129:                 *            or<code>null</code> if dynamically generated.
1130:                 *
1131:                 * @task TODO: figure out how to unhack legend parameters such as WIDTH,
1132:                 *       HEIGHT and FORMAT
1133:                 */
1134:                protected void handleLegendURL(Object layer) {
1135:                    LegendURL legend = null;
1136:                    String layerName = null;
1137:
1138:                    if (layer instanceof  FeatureTypeInfo) {
1139:                        legend = ((FeatureTypeInfo) layer).getLegendURL();
1140:                        layerName = ((FeatureTypeInfo) layer).getName();
1141:                    } else if (layer instanceof  CoverageInfo) {
1142:                        layerName = ((CoverageInfo) layer).getName();
1143:                    }
1144:
1145:                    if (legend != null) {
1146:                        if (LOGGER.isLoggable(Level.FINE)) {
1147:                            LOGGER.fine("using user supplied legend URL");
1148:                        }
1149:
1150:                        AttributesImpl attrs = new AttributesImpl();
1151:                        attrs.addAttribute("", "width", "width", "", String
1152:                                .valueOf(legend.getWidth()));
1153:                        attrs.addAttribute("", "height", "height", "", String
1154:                                .valueOf(legend.getHeight()));
1155:
1156:                        start("LegendURL", attrs);
1157:
1158:                        element("Format", legend.getFormat());
1159:                        attrs.clear();
1160:                        attrs.addAttribute("", "xmlns:xlink", "xmlns:xlink",
1161:                                "", XLINK_NS);
1162:                        attrs.addAttribute(XLINK_NS, "type", "xlink:type", "",
1163:                                "simple");
1164:                        attrs.addAttribute(XLINK_NS, "href", "xlink:href", "",
1165:                                legend.getOnlineResource());
1166:
1167:                        element("OnlineResource", null, attrs);
1168:
1169:                        end("LegendURL");
1170:                    } else {
1171:                        String defaultFormat = GetLegendGraphicRequest.DEFAULT_FORMAT;
1172:
1173:                        if (!GetLegendGraphicResponse.supportsFormat(
1174:                                defaultFormat, applicationContext)) {
1175:                            if (LOGGER.isLoggable(Level.WARNING)) {
1176:                                LOGGER
1177:                                        .warning(new StringBuffer(
1178:                                                "Default legend format (")
1179:                                                .append(defaultFormat)
1180:                                                .append(
1181:                                                        ")is not supported (jai not available?), can't add LegendURL element")
1182:                                                .toString());
1183:                            }
1184:
1185:                            return;
1186:                        }
1187:
1188:                        if (LOGGER.isLoggable(Level.FINE)) {
1189:                            LOGGER
1190:                                    .fine("Adding GetLegendGraphic call as LegendURL");
1191:                        }
1192:
1193:                        AttributesImpl attrs = new AttributesImpl();
1194:                        attrs
1195:                                .addAttribute(
1196:                                        "",
1197:                                        "width",
1198:                                        "width",
1199:                                        "",
1200:                                        String
1201:                                                .valueOf(GetLegendGraphicRequest.DEFAULT_WIDTH));
1202:
1203:                        // DJB: problem here is that we do not know the size of the
1204:                        // legend apriori - we need
1205:                        // to make one and find its height. Not the best way, but it
1206:                        // would work quite well.
1207:                        // This was advertising a 20*20 icon, but actually producing
1208:                        // ones of a different size.
1209:                        // An alternative is to just scale the resulting icon to what
1210:                        // the server requested, but this isnt
1211:                        // the nicest thing since warped images dont look nice. The
1212:                        // client should do the warping.
1213:
1214:                        // however, to actually estimate the size is a bit difficult.
1215:                        // I'm going to do the scaling
1216:                        // so it obeys the what the request says. For people with a
1217:                        // problem with that should consider
1218:                        // changing the default size here so that the request is for the
1219:                        // correct size.
1220:                        attrs
1221:                                .addAttribute(
1222:                                        "",
1223:                                        "height",
1224:                                        "height",
1225:                                        "",
1226:                                        String
1227:                                                .valueOf(GetLegendGraphicRequest.DEFAULT_HEIGHT));
1228:
1229:                        start("LegendURL", attrs);
1230:
1231:                        element("Format", defaultFormat);
1232:                        attrs.clear();
1233:
1234:                        StringBuffer onlineResource = new StringBuffer(
1235:                                RequestUtils.proxifiedBaseURL(request
1236:                                        .getBaseUrl(), request.getServiceRef()
1237:                                        .getGeoServer().getProxyBaseUrl()));
1238:                        onlineResource.append("wms/GetLegendGraphic?VERSION=");
1239:                        onlineResource
1240:                                .append(GetLegendGraphicRequest.SLD_VERSION);
1241:                        onlineResource.append("&FORMAT=");
1242:                        onlineResource.append(defaultFormat);
1243:                        onlineResource.append("&WIDTH=");
1244:                        onlineResource
1245:                                .append(GetLegendGraphicRequest.DEFAULT_WIDTH);
1246:                        onlineResource.append("&HEIGHT=");
1247:                        onlineResource
1248:                                .append(GetLegendGraphicRequest.DEFAULT_HEIGHT);
1249:                        onlineResource.append("&LAYER=");
1250:                        onlineResource.append(layerName);
1251:
1252:                        attrs.addAttribute("", "xmlns:xlink", "xmlns:xlink",
1253:                                "", XLINK_NS);
1254:                        attrs.addAttribute(XLINK_NS, "type", "xlink:type", "",
1255:                                "simple");
1256:                        attrs.addAttribute(XLINK_NS, "href", "xlink:href", "",
1257:                                onlineResource.toString());
1258:                        element("OnlineResource", null, attrs);
1259:
1260:                        end("LegendURL");
1261:                    }
1262:                }
1263:
1264:                /**
1265:                 * Encodes a LatLonBoundingBox for the given Envelope.
1266:                 *
1267:                 * @param bbox
1268:                 */
1269:                private void handleLatLonBBox(Envelope bbox) {
1270:                    String minx = String.valueOf(bbox.getMinX());
1271:                    String miny = String.valueOf(bbox.getMinY());
1272:                    String maxx = String.valueOf(bbox.getMaxX());
1273:                    String maxy = String.valueOf(bbox.getMaxY());
1274:
1275:                    AttributesImpl bboxAtts = new AttributesImpl();
1276:                    bboxAtts.addAttribute("", "minx", "minx", "", minx);
1277:                    bboxAtts.addAttribute("", "miny", "miny", "", miny);
1278:                    bboxAtts.addAttribute("", "maxx", "maxx", "", maxx);
1279:                    bboxAtts.addAttribute("", "maxy", "maxy", "", maxy);
1280:
1281:                    element("LatLonBoundingBox", null, bboxAtts);
1282:                }
1283:
1284:                /**
1285:                 * adds a comment to the output xml file. THIS IS A BIG HACK. TODO: do
1286:                 * this in the correct manner!
1287:                 *
1288:                 * @param comment
1289:                 */
1290:                public void comment(String comment) {
1291:                    if (contentHandler instanceof  TransformerIdentityImpl) // HACK HACK
1292:                    // HACK --
1293:                    // not sure
1294:                    // of the
1295:                    // proper
1296:                    // way to do
1297:                    // this.
1298:                    {
1299:                        try {
1300:                            TransformerIdentityImpl ch = (TransformerIdentityImpl) contentHandler;
1301:                            ch.comment(comment.toCharArray(), 0, comment
1302:                                    .length());
1303:                        } catch (Exception e) {
1304:                            e.printStackTrace();
1305:                        }
1306:                    }
1307:                }
1308:
1309:                /**
1310:                 * Encodes a BoundingBox for the given Envelope.
1311:                 *
1312:                 * @param bbox
1313:                 */
1314:                private void handleBBox(Envelope bbox, String SRS) {
1315:                    String minx = String.valueOf(bbox.getMinX());
1316:                    String miny = String.valueOf(bbox.getMinY());
1317:                    String maxx = String.valueOf(bbox.getMaxX());
1318:                    String maxy = String.valueOf(bbox.getMaxY());
1319:
1320:                    AttributesImpl bboxAtts = new AttributesImpl();
1321:                    bboxAtts.addAttribute("", "SRS", "SRS", "", SRS);
1322:                    bboxAtts.addAttribute("", "minx", "minx", "", minx);
1323:                    bboxAtts.addAttribute("", "miny", "miny", "", miny);
1324:                    bboxAtts.addAttribute("", "maxx", "maxx", "", maxx);
1325:                    bboxAtts.addAttribute("", "maxy", "maxy", "", maxy);
1326:
1327:                    element("BoundingBox", null, bboxAtts);
1328:                }
1329:            }
1330:        }
1331:
1332:        /**
1333:         * A Class to manage the WMS Layer structure
1334:         *
1335:         * @author fabiania
1336:         *
1337:         * TODO To change the template for this generated type comment go to Window -
1338:         * Preferences - Java - Code Style - Code Templates
1339:         */
1340:        class LayerTree {
1341:            private String name;
1342:            private Collection childrens;
1343:            private Collection data;
1344:
1345:            /**
1346:             * @param name
1347:             *            String
1348:             */
1349:            public LayerTree(String name) {
1350:                this .name = name;
1351:                this .childrens = new ArrayList();
1352:                this .data = new ArrayList();
1353:            }
1354:
1355:            /**
1356:             * @param c
1357:             *            Collection
1358:             */
1359:            public LayerTree(Collection c) {
1360:                this .name = "";
1361:                this .childrens = new ArrayList();
1362:                this .data = new ArrayList();
1363:
1364:                for (Iterator it = c.iterator(); it.hasNext();) {
1365:                    Object element = it.next();
1366:
1367:                    if (element instanceof  CoverageInfo) {
1368:                        CoverageInfo cLayer = (CoverageInfo) element;
1369:
1370:                        if (cLayer.isEnabled()) {
1371:                            String wmsPath = (((cLayer.getWmsPath() != null) && (cLayer
1372:                                    .getWmsPath().length() > 0)) ? cLayer
1373:                                    .getWmsPath() : "/");
1374:
1375:                            if (wmsPath.startsWith("/")) {
1376:                                wmsPath = wmsPath
1377:                                        .substring(1, wmsPath.length());
1378:                            }
1379:
1380:                            String[] treeStructure = wmsPath.split("/");
1381:                            addToNode(this , treeStructure, cLayer);
1382:                        }
1383:                    } else if (element instanceof  FeatureTypeInfo) {
1384:                        FeatureTypeInfo fLayer = (FeatureTypeInfo) element;
1385:
1386:                        if (fLayer.isEnabled()) {
1387:                            String wmsPath = (((fLayer.getWmsPath() != null) && (fLayer
1388:                                    .getWmsPath().length() > 0)) ? fLayer
1389:                                    .getWmsPath() : "/");
1390:
1391:                            if (wmsPath.startsWith("/")) {
1392:                                wmsPath = wmsPath
1393:                                        .substring(1, wmsPath.length());
1394:                            }
1395:
1396:                            String[] treeStructure = wmsPath.split("/");
1397:                            addToNode(this , treeStructure, fLayer);
1398:                        }
1399:                    }
1400:                }
1401:            }
1402:
1403:            /**
1404:             * @param tree
1405:             * @param treeStructure
1406:             * @param layer
1407:             */
1408:            private void addToNode(LayerTree tree, String[] treeStructure,
1409:                    CoverageInfo layer) {
1410:                final int length = treeStructure.length;
1411:
1412:                if ((length == 0) || (treeStructure[0].length() == 0)) {
1413:                    tree.data.add(layer);
1414:                } else {
1415:                    LayerTree node = tree.getNode(treeStructure[0]);
1416:
1417:                    if (node == null) {
1418:                        node = new LayerTree(treeStructure[0]);
1419:                        tree.childrens.add(node);
1420:                    }
1421:
1422:                    String[] subTreeStructure = new String[length - 1];
1423:                    System.arraycopy(treeStructure, 1, subTreeStructure, 0,
1424:                            length - 1);
1425:                    addToNode(node, subTreeStructure, layer);
1426:                }
1427:            }
1428:
1429:            private void addToNode(LayerTree tree, String[] treeStructure,
1430:                    FeatureTypeInfo layer) {
1431:                final int length = treeStructure.length;
1432:
1433:                if ((length == 0) || (treeStructure[0].length() == 0)) {
1434:                    tree.data.add(layer);
1435:                } else {
1436:                    LayerTree node = tree.getNode(treeStructure[0]);
1437:
1438:                    if (node == null) {
1439:                        node = new LayerTree(treeStructure[0]);
1440:                        tree.childrens.add(node);
1441:                    }
1442:
1443:                    String[] subTreeStructure = new String[length - 1];
1444:                    System.arraycopy(treeStructure, 1, subTreeStructure, 0,
1445:                            length - 1);
1446:                    addToNode(node, subTreeStructure, layer);
1447:                }
1448:            }
1449:
1450:            /**
1451:             * @param string
1452:             * @return
1453:             */
1454:            public LayerTree getNode(String name) {
1455:                LayerTree node = null;
1456:
1457:                for (Iterator it = this .childrens.iterator(); it.hasNext();) {
1458:                    LayerTree tmpNode = (LayerTree) it.next();
1459:
1460:                    if (tmpNode.name.equals(name)) {
1461:                        node = tmpNode;
1462:                    }
1463:                }
1464:
1465:                return node;
1466:            }
1467:
1468:            public Collection getChildrens() {
1469:                return childrens;
1470:            }
1471:
1472:            public Collection getData() {
1473:                return data;
1474:            }
1475:
1476:            public String getName() {
1477:                return name;
1478:            }
1479:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.