/** @see org.geoserver.config.GeoServerInitializer#initialize(org.geoserver.config.GeoServer) */ public void initialize(final GeoServer geoServer) throws Exception { LOGGER.info( "Initializing GeoServer specific GWC configuration from " + GWCConfigPersister.GWC_CONFIG_FILE); final Version currentVersion = new Version("1.0.0"); final File configFile = configPersister.findConfigFile(); if (configFile == null) { LOGGER.fine("GWC's GeoServer specific configuration not found, creating with old defaults"); GWCConfig oldDefaults = GWCConfig.getOldDefaults(); oldDefaults.setVersion(currentVersion.toString()); upgradeWMSIntegrationConfig(geoServer, oldDefaults); createDefaultTileLayerInfos(oldDefaults); configPersister.save(oldDefaults); } final GWCConfig config = configPersister.getConfig(); final Version version = new Version(config.getVersion()); if (currentVersion.compareTo(version) > 0) { // got the global config file, so old defaults are already in place if need be. Now // check whether we need to migrate the configuration from the Layer/GroupInfo metadata // maps to the tile layer catalog store moveTileLayerInfosToTileLayerCatalog(); config.setVersion(currentVersion.toString()); configPersister.save(config); } final GWCConfig gwcConfig = configPersister.getConfig(); checkNotNull(gwcConfig); }
/** * Returns a version object for the specified version string optionally returning null when the * version string does not match one of the available WMS versions. * * @param version The version string. * @param exact If set to false, a version object will always be returned. If set to true only a * version matching on of the available wms versions will be returned. * @return */ public static Version version(String version, boolean exact) { if (version == null || 0 == version.trim().length()) { return null; } if (VERSION_1_1_1.toString().equals(version)) { return VERSION_1_1_1; } else if (VERSION_1_3_0.toString().equals(version)) { return VERSION_1_3_0; } return exact ? null : new Version(version); }
@Override public String mimeType(Version version) { if (version != null && VERSION_11.equals(version)) { return MIMETYPE_11; } return MIMETYPE_10; }
/** * Returns a supported version according to the version negotiation rules in section 6.2.4 of the * WMS 1.3.0 spec. * * <p>For instance: <u> * <li>request version not provided? -> higher version supported * <li>requested version supported? -> that same version * <li>requested version < lowest supported version? -> lowest supported * <li>requested version > lowest supported version? -> higher supported version that's lower than * the requested version </u> * * @param requestedVersion the request version, or {@code null} if unspecified * @return */ public static Version negotiateVersion(final Version requestedVersion) { if (null == requestedVersion) { return VERSION_1_3_0; } if (VERSION_1_1_1.equals(requestedVersion)) { return VERSION_1_1_1; } if (VERSION_1_3_0.equals(requestedVersion)) { return VERSION_1_3_0; } if (requestedVersion.compareTo(VERSION_1_3_0) < 0) { return VERSION_1_1_1; } return VERSION_1_3_0; }
/** * Transforms a crs identifier to its internal representation based on the specified WMS version. * * <p>In version 1.3 of WMS geographic coordinate systems are to be ordered y/x or * latitude/longitude. The only possible way to represent this internally is to use the explicit * epsg namespace "urn:x-ogc:def:crs:EPSG:". This method essentially replaces the traditional * "EPSG:" namespace with the explicit. */ public static String toInternalSRS(String srs, Version version) { if (VERSION_1_3_0.equals(version)) { if (srs != null && srs.toUpperCase().startsWith("EPSG:")) { srs = srs.toUpperCase().replace("EPSG:", "urn:x-ogc:def:crs:EPSG:"); } } return srs; }
@Override public void encode( StyledLayerDescriptor sld, Version version, boolean pretty, OutputStream output) throws IOException { if (version != null && VERSION_11.compareTo(version) == 0) { encode11(sld, pretty, output); } else { encode10(sld, pretty, output); } }
@Override public void encodeValue(Object value, Class type, StringBuffer sql) { if (byte[].class.equals(type)) { byte[] input = (byte[]) value; // check postgres version, if > 9 default encoding is hex if (pgsqlVersion.compareTo(PGSQL_V_9_1) >= 0) { encodeByteArrayAsHex(input, sql); } else { encodeByteArrayAsEscape(input, sql); } } else { super.encodeValue(value, type, sql); } }
@Override public List<Exception> validate(Object input, Version version, EntityResolver entityResolver) throws IOException { if (version == null) { Object[] versionAndReader = getVersionAndReader(input); version = (Version) versionAndReader[0]; input = versionAndReader[1]; } if (version != null && VERSION_11.compareTo(version) == 0) { return validate11(input, entityResolver); } else { return validate10(input, entityResolver); } }
@Override public StyledLayerDescriptor parse( Object input, Version version, ResourceLocator resourceLocator, EntityResolver entityResolver) throws IOException { if (version == null) { Object[] versionAndReader = getVersionAndReader(input); version = (Version) versionAndReader[0]; input = versionAndReader[1]; } if (VERSION_11.compareTo(version) == 0) { return parse11(input, resourceLocator, entityResolver); } else { return parse10(input, resourceLocator, entityResolver); } }
@SuppressWarnings({"rawtypes", "unchecked"}) @Override public Object read(Object req, Map kvp, Map rawKvp) throws Exception { GetFeatureInfoRequest request = (GetFeatureInfoRequest) super.read(req, kvp, rawKvp); request.setRawKvp(rawKvp); GetMapRequest getMapPart = new GetMapRequest(); try { getMapPart = getMapReader.read(getMapPart, kvp, rawKvp); } catch (ServiceException se) { throw se; } catch (Exception e) { throw new ServiceException(e); } request.setGetMapRequest(getMapPart); List<MapLayerInfo> getMapLayers = getMapPart.getLayers(); if ((getMapPart.getSldBody() != null || getMapPart.getSld() != null) && (rawKvp.get("QUERY_LAYERS") == null || "".equals(rawKvp.get("QUERY_LAYERS")))) { // in this case we assume all layers in SLD body are to be queried (GS own extension)( request.setQueryLayers(getMapLayers); } else { request.setQueryLayers( new MapLayerInfoKvpParser("QUERY_LAYERS", wms) .parse((String) rawKvp.get("QUERY_LAYERS"))); } if (request.getQueryLayers().isEmpty()) { throw new ServiceException( "No QUERY_LAYERS has been requested, or no " + "queriable layer in the request anyways"); } if (kvp.containsKey("propertyName")) { List<List<String>> propertyNames = (List<List<String>>) kvp.get("propertyName"); if (propertyNames.size() == 1 && request.getQueryLayers().size() > 1) { // assume we asked the same list for all layers while (propertyNames.size() < request.getQueryLayers().size()) { propertyNames.add(propertyNames.get(0)); } } if (propertyNames.size() != request.getQueryLayers().size()) { throw new ServiceException( "Mismatch between the property name set count " + propertyNames.size() + " and the query layers count " + request.getQueryLayers().size(), "InvalidParameter", "propertyName"); } request.setPropertyNames(propertyNames); } // make sure they are a subset of layers List<MapLayerInfo> queryLayers = new ArrayList<MapLayerInfo>(request.getQueryLayers()); queryLayers.removeAll(getMapLayers); if (queryLayers.size() > 0) { // we've already expanded base layers so let's avoid list the names, they are not // the original ones anymore throw new ServiceException( "QUERY_LAYERS contains layers not cited in LAYERS. " + "It should be a proper subset of those instead"); } for (MapLayerInfo l : request.getQueryLayers()) { LayerInfo layerInfo = l.getLayerInfo(); if (!wms.isQueryable(layerInfo)) { throw new ServiceException( "Layer " + l.getName() + " is not queryable", WMSErrorCode.LAYER_NOT_QUERYABLE.get(request.getVersion()), "QUERY_LAYERS"); } } String format = (String) (kvp.containsKey("INFO_FORMAT") ? kvp.get("INFO_FORMAT") : null); if (format == null) { format = "text/plain"; } else { List<String> infoFormats = wms.getAvailableFeatureInfoFormats(); if (!infoFormats.contains(format)) { throw new ServiceException( "Invalid format '" + format + "', supported formats are " + infoFormats, "InvalidFormat", "info_format"); } if (wms.getAllowedFeatureInfoFormats().contains(format) == false) throw wms.unallowedGetFeatureInfoFormatException(format); } request.setInfoFormat(format); request.setFeatureCount(1); // DJB: according to the WMS spec (7.3.3.7 FEATURE_COUNT) this // should be 1. also tested for by cite try { int maxFeatures = Integer.parseInt(String.valueOf(kvp.get("FEATURE_COUNT"))); request.setFeatureCount(maxFeatures); } catch (NumberFormatException ex) { // do nothing, FEATURE_COUNT is optional } Version version = wms.negotiateVersion(request.getVersion()); request.setVersion(version.toString()); // JD: most wms 1.3 client implementations still use x/y rather than i/j, so we support those // too when i/j not specified when not running in strict cite compliance mode String colPixel, rowPixel; if (version.compareTo(WMS.VERSION_1_3_0) >= 0) { colPixel = "I"; rowPixel = "J"; if (!kvp.containsKey(colPixel) && !kvp.containsKey(rowPixel)) { if (!wms.getServiceInfo().isCiteCompliant() && kvp.containsKey("X") && kvp.containsKey("Y")) { colPixel = "X"; rowPixel = "Y"; } } } else { colPixel = "X"; rowPixel = "Y"; } try { String colParam = String.valueOf(kvp.get(colPixel)); String rowParam = String.valueOf(kvp.get(rowPixel)); int x = Integer.parseInt(colParam); int y = Integer.parseInt(rowParam); // ensure x/y in dimension of image if (x < 0 || x > getMapPart.getWidth() || y < 0 || y > getMapPart.getHeight()) { throw new ServiceException( String.format( "%d, %d not in dimensions of image: %d, %d", x, y, getMapPart.getWidth(), getMapPart.getHeight()), "InvalidPoint"); } request.setXPixel(x); request.setYPixel(y); } catch (NumberFormatException ex) { String msg = colPixel + " and " + rowPixel + " incorrectly specified"; throw new ServiceException(msg, "InvalidPoint"); } return request; }
/** * Parses a map of key value pairs. * * <p>Important: This method modifies the map, overriding original values with parsed values. * * <p>This routine performs a lookup of {@link KvpParser} to parse the kvp entries. * * <p>If an individual parse fails, this method saves the exception, and adds it to the list that * is returned. * * @param rawKvp raw or unparsed kvp. * @return A list of errors that occured. */ public static List<Throwable> parse(Map kvp) { // look up parser objects Collection parsers = GeoServerExtensions.extensions(KvpParser.class); // strip out parsers which do not match current service/request/version String service = (String) kvp.get("service"); String version = (String) kvp.get("version"); String request = (String) kvp.get("request"); for (Iterator p = parsers.iterator(); p.hasNext(); ) { KvpParser parser = (KvpParser) p.next(); if (parser.getService() != null && !parser.getService().equalsIgnoreCase(service)) { p.remove(); continue; } if (parser.getVersion() != null && !parser.getVersion().toString().equals(version)) { p.remove(); continue; } if (parser.getRequest() != null && !parser.getRequest().equalsIgnoreCase(request)) { p.remove(); } } // parser the kvp's ArrayList<Throwable> errors = new ArrayList<Throwable>(); for (Iterator itr = kvp.entrySet().iterator(); itr.hasNext(); ) { Map.Entry entry = (Map.Entry) itr.next(); String key = (String) entry.getKey(); // find the parser for this key value pair KvpParser parser = null; for (Iterator pitr = parsers.iterator(); pitr.hasNext(); ) { KvpParser candidate = (KvpParser) pitr.next(); if (key.equalsIgnoreCase(candidate.getKey())) { if (parser == null) { parser = candidate; } else { String curService = parser.getService(); Version curVersion = parser.getVersion(); String trgService = candidate.getService(); Version trgVersion = candidate.getVersion(); // determine if this parser more closely matches the request if (curService == null) { // if target service matches, it is a closer match if (trgService != null && trgService.equalsIgnoreCase(service)) { parser = candidate; } } else { if (trgService != null && trgService.equalsIgnoreCase(service)) { // both match, filter by version if (trgVersion != null) { if (curVersion == null && trgVersion.toString().equals(version)) { parser = candidate; } } else { if (curVersion == null) { // ambiguous, unable to match // TODO: use request throw new IllegalStateException( "Multiple kvp parsers: " + parser + "," + candidate); } } } } } } } // parse the value Object parsed = null; if (parser != null) { try { if (entry.getValue() instanceof String) { String value = (String) entry.getValue(); parsed = parser.parse(value); } else { String[] values = (String[]) entry.getValue(); List result = new ArrayList(); for (String v : values) { result.add(parser.parse(v)); } parsed = result; } } catch (Throwable t) { // dont throw any exceptions yet, befor the service is // known errors.add(t); } } // if noone could parse, just set to string value if (parsed != null) { entry.setValue(parsed); } } return errors; }