| 193 | | |
| 194 | | private String getCapabilitiesHeader() throws GeoWebCacheException { |
| 195 | | String wms = fetchOrigionalWMSCapabilitiesDocument(); |
| 196 | | |
| 197 | | if (wms == null) { |
| 198 | | throw new GeoWebCacheException( |
| 199 | | "Unable to retrieve original WMS Capabilities document"); |
| 200 | | } |
| 201 | | |
| 202 | | int split = wms.indexOf("<VendorSpecificCapabilities/>"); |
| 203 | | if (split != -1) { |
| 204 | | // we have an empty VendorSpecificCapabilities to fill in... |
| 205 | | String header = wms.substring(0, split); |
| 206 | | return header + "\n<VendorSpecificCapabilities>"; |
| 207 | | } |
| 208 | | split = wms.indexOf("</VendorSpecificCapabilities>"); |
| 209 | | |
| 210 | | // Was never read anyway |
| 211 | | //if (split != -1) { |
| 212 | | // we have an existing VendorSpecificCapabilities to add to |
| 213 | | // String header = wms.substring(0, split); |
| 214 | | //} |
| 215 | | |
| 216 | | // look for <UserDefinedSymbolization .. VendorSpecificCapabilities goes |
| 217 | | // before this element |
| 218 | | split = wms.indexOf("<UserDefinedSymbolization"); |
| 219 | | if (split == -1) { |
| 220 | | // look for <Layer> ... VendorSpecificParameters goes before this |
| 221 | | // element |
| 222 | | split = wms.indexOf("<Layer"); |
| 223 | | } |
| 224 | | String header = wms.substring(0, split); |
| 225 | | |
| 226 | | return header + "\n<VendorSpecificCapabilities>"; |
| 227 | | } |
| 228 | | |
| 229 | | private String getCapabilitiesFooter() throws GeoWebCacheException { |
| 230 | | // return "\n</VendorSpecificCapabilities>" + |
| 231 | | // "\n</WMT_MS_Capabilities>"; |
| 232 | | String wms = fetchOrigionalWMSCapabilitiesDocument(); |
| 233 | | int split = wms.indexOf("<VendorSpecificCapabilities/>"); |
| 234 | | if (split != -1) { |
| 235 | | // we have an empty VendorSpecificCapabilities to fill in... |
| 236 | | String footer = wms.substring(split + 29); |
| 237 | | return "\n</VendorSpecificCapabilities>" + footer; |
| 238 | | } |
| 239 | | split = wms.indexOf("<VendorSpecificCapabilities/>"); |
| 240 | | if (split != -1) { |
| 241 | | // we have an existing VendorSpecificCapabilities to add to |
| 242 | | String footer = wms.substring(split + 28); |
| 243 | | return "\n</VendorSpecificCapabilities>" + footer; |
| 244 | | } |
| 245 | | // look for <UserDefinedSymbolization .. VendorSpecificCapabilities goes |
| 246 | | // before this element |
| 247 | | split = wms.indexOf("<UserDefinedSymbolization"); |
| 248 | | if (split == -1) { |
| 249 | | // look for <Layer> ... VendorSpecificParameters goes before this |
| 250 | | // element |
| 251 | | split = wms.indexOf("<Layer"); |
| 252 | | } |
| 253 | | String footer = wms.substring(split); |
| 254 | | return "\n</VendorSpecificCapabilities>" + footer; |
| 255 | | } |
| 256 | | |
| 257 | | /** |
| 258 | | * Fetch the original WMS capabilities document (we will add our vendor |
| 259 | | * specific parameters here). |
| 260 | | * <p> |
| 261 | | * Currently this is returned as a String; in the future we can make use of |
| 262 | | * the GeoTools WMSCapabilities data structure (and strip out any layers |
| 263 | | * that are not mentioned explicitly). |
| 264 | | * |
| 265 | | * @return The original WMS capabilities document prior to processing |
| 266 | | * @throws GeoWebCacheException |
| 267 | | */ |
| 268 | | synchronized String fetchOrigionalWMSCapabilitiesDocument() throws GeoWebCacheException { |
| 269 | | if (getCapsStr != null) { |
| 270 | | return getCapsStr; |
| 271 | | } |
| 272 | | StringBuffer buf = new StringBuffer(); |
| 273 | | |
| 274 | | if (getCapConfigs == null) { |
| 275 | | throw new GeoWebCacheException("No configuration object available" + |
| 276 | | " to use for WMS Capabilities"); |
| 277 | | } |
| 278 | | Iterator<Configuration> configIter = getCapConfigs.iterator(); |
| 279 | | CONFIG: while (configIter.hasNext()) { |
| 280 | | Map<String, TileLayer> configLayers = null; |
| 281 | | Configuration config = configIter.next(); |
| 282 | | try { |
| 283 | | configLayers = config.getTileLayers(); |
| 284 | | } catch (GeoWebCacheException gwce) { |
| 285 | | log.error(gwce.getMessage()); |
| 286 | | log.error("Failed to add layers from "+ config.getIdentifier()); |
| 287 | | } |
| 288 | | if (configLayers != null && configLayers.size() > 0) { |
| 289 | | for (TileLayer layer : configLayers.values()) { |
| 290 | | if (!(layer instanceof WMSLayer)) { |
| 291 | | continue; // skip! |
| 292 | | } |
| 293 | | WMSLayer wmsLayer = (WMSLayer) layer; |
| 294 | | for (String url : wmsLayer.getWMSurl()) { |
| 295 | | try { |
| 296 | | URL capabilitiesURL = new URL( |
| 297 | | url+ "?REQUEST=GetCapabilities&SERVICE=WMS&VESION=1.1.0"); |
| 298 | | URLConnection connection = capabilitiesURL.openConnection(); |
| 299 | | InputStream input = connection.getInputStream(); |
| 300 | | InputStreamReader reader = new InputStreamReader(input); |
| 301 | | BufferedReader process = new BufferedReader(reader); |
| 302 | | |
| 303 | | buf = new StringBuffer(); |
| 304 | | String line; |
| 305 | | while ((line = process.readLine()) != null) { |
| 306 | | buf.append(line); |
| 307 | | buf.append("\n"); |
| 308 | | } |
| 309 | | if (buf.length() != 0) { |
| 310 | | break CONFIG; // we managed to read a |
| 311 | | // capabilities into buf |
| 312 | | } |
| 313 | | /* |
| 314 | | * // TODO only use the parts of the capabilities |
| 315 | | * file that // are mentioned in our configuration! |
| 316 | | * |
| 317 | | * WebMapServer wms = new |
| 318 | | * WebMapServer(capabilitiesURL); WMSCapabilities |
| 319 | | * capabilities = wms.getCapabilities(); |
| 320 | | */ |
| 321 | | } catch (Throwable notConnected) { |
| 322 | | // continue WMSURL |
| 323 | | } |
| 324 | | } |
| 325 | | } |
| 326 | | } else { |
| 327 | | log.error("Configuration " + config.getIdentifier() |
| 328 | | + " contained no layers."); |
| 329 | | } |
| 330 | | } |
| 331 | | getCapsStr = buf.toString(); |
| 332 | | return getCapsStr; |
| 333 | | } |
| 334 | | |
| 335 | | public void setConfig(List<Configuration> configs) { |
| 336 | | this.getCapConfigs = configs; |
| 337 | | } |
| 338 | | |
| 339 | | /** |
| 340 | | * |
| 341 | | * @param tl |
| 342 | | * @return |
| 343 | | */ |
| 344 | | private String getTileSets(TileLayer tl) throws GeoWebCacheException { |
| 345 | | String ret = ""; |
| 346 | | |
| 347 | | List<MimeType> mimeList = tl.getMimeTypes(); |
| 348 | | String strStyles = tl.getStyles(); |
| 349 | | if (strStyles == null) { |
| 350 | | strStyles = ""; |
| 351 | | } |
| 352 | | |
| 353 | | Iterator<Grid> iter = tl.getGrids().values().iterator(); |
| 354 | | while (iter.hasNext()) { |
| 355 | | Grid grid = iter.next(); |
| 356 | | |
| 357 | | // These should be adjusted bounds! |
| 358 | | String[] strBounds = doublesToStrings(grid.getBounds().coords); |
| 359 | | String strResolutions = getResolutionString(grid.getResolutions()); |
| 360 | | String strName = tl.getName(); |
| 361 | | |
| 362 | | for (MimeType mime : mimeList) { |
| 363 | | String strFormat = mime.getFormat(); |
| 364 | | ret += getTileSet(strName, grid.getSRS().toString(), strBounds, |
| 365 | | strStyles, strResolutions, strFormat); |
| 366 | | } |
| 367 | | } |
| 368 | | |
| 369 | | return ret; |
| 370 | | } |
| 371 | | |
| 372 | | private String getTileSet(String strName, String strSRS, |
| 373 | | String[] strBounds, String strStyles, String strResolutions, |
| 374 | | String strFormat) { |
| 375 | | return "\n<TileSet>" |
| 376 | | + "<SRS>" + strSRS + "</SRS>" |
| 377 | | + "<BoundingBox srs=\"" + strSRS + "\"" + " minx=\"" |
| 378 | | + strBounds[0] + "\"" + " miny=\"" + strBounds[1] + "\"" |
| 379 | | + " maxx=\"" + strBounds[2] + "\"" + " maxy=\"" + strBounds[3] |
| 380 | | + "\" />" |
| 381 | | + "<Resolutions>" + strResolutions + "</Resolutions>" |
| 382 | | + "<Width>256</Width>" |
| 383 | | + "<Height>256</Height>" |
| 384 | | + "<Format>" + strFormat + "</Format>" |
| 385 | | + "<Layers>" + strName + "</Layers>" |
| 386 | | + "<Styles>" + strStyles + "</Styles>" |
| 387 | | + "</TileSet>"; |
| 388 | | } |
| 389 | | |
| 390 | | private String[] doublesToStrings(double[] doubles) { |
| 391 | | String[] ret = new String[doubles.length]; |
| 392 | | for (int i = 0; i < doubles.length; i++) { |
| 393 | | ret[i] = Double.toString(doubles[i]); |
| 394 | | } |
| 395 | | return ret; |
| 396 | | } |
| 397 | | |
| 398 | | private String getResolutionString(double[] resolutions) { |
| 399 | | String ret = ""; |
| 400 | | for (int i = 0; i < resolutions.length; i++) { |
| 401 | | ret += Double.toString(resolutions[i]) + " "; |
| 402 | | } |
| 403 | | return ret; |
| 404 | | } |
| 405 | | |
| 406 | | /** |
| 407 | | * Should only be used for getCapabilities |
| 408 | | * |
| 409 | | * @param response |
| 410 | | * @param data |
| 411 | | * @throws IOException |
| 412 | | */ |
| 413 | | private void writeData(HttpServletResponse response, byte[] data) |
| 414 | | throws IOException { |
| 415 | | |
| 416 | | // Did we get anything? |
| 417 | | if (data == null || data.length == 0) { |
| 418 | | log.trace("sendData() had nothing to return"); |
| 419 | | response.setStatus(HttpServletResponse.SC_NO_CONTENT); |
| 420 | | return; |
| 421 | | } |
| 422 | | |
| 423 | | log.trace("sendData() Sending data."); |
| 424 | | response.setStatus(HttpServletResponse.SC_OK); |
| 425 | | response.setContentType("application/vnd.ogc.wms_xml"); |
| 426 | | response.setContentLength(data.length); |
| 427 | | try { |
| 428 | | OutputStream os = response.getOutputStream(); |
| 429 | | os.write(data); |
| 430 | | os.flush(); |
| 431 | | } catch (IOException ioe) { |
| 432 | | log.debug("Caught IOException" + ioe.getMessage()); |
| | 180 | |
| | 181 | public void setProxyNonTiledRequests(String trueFalse) { |
| | 182 | this.proxyNonTiledRequests = Boolean.parseBoolean(trueFalse); |
| | 183 | if(this.proxyNonTiledRequests) { |
| | 184 | log.info("Will proxy requests that miss tiled=true to backend."); |
| | 185 | } else { |
| | 186 | log.info("Will NOT proxy requests that miss tiled=true to backend."); |