void setupExtras(org.geoserver.data.test.SystemTestData testData, Catalog catalog)
      throws IOException {
    // associate Lakes to Buildings as an extra style
    LayerInfo buildings = catalog.getLayerByName(getLayerId(BUILDINGS));
    buildings.getStyles().add(catalog.getStyleByName(LAKES.getLocalPart()));
    catalog.save(buildings);

    // add a layer group
    CatalogFactory factory = catalog.getFactory();
    LayerGroupInfo globalGroup = factory.createLayerGroup();
    globalGroup.setName(LAKES_GROUP);
    globalGroup.getLayers().add(catalog.getLayerByName(getLayerId(LAKES)));
    globalGroup.getLayers().add(catalog.getLayerByName(getLayerId(FORESTS)));
    globalGroup.getLayers().add(catalog.getLayerByName(getLayerId(BRIDGES)));
    catalog.add(globalGroup);

    // add a layer group containing a layer group
    LayerGroupInfo nestGroup = factory.createLayerGroup();
    nestGroup.setName(NEST_GROUP);
    nestGroup.getLayers().add(catalog.getLayerByName(getLayerId(LAKES)));
    nestGroup.getLayers().add(globalGroup);
    catalog.add(nestGroup);

    // add a workspace specific style
    WorkspaceInfo ws = catalog.getWorkspaceByName(CITE_PREFIX);
    testData.addStyle(ws, WS_STYLE, "Streams.sld", SystemTestData.class, catalog);
  };
Пример #2
0
  /** @return the list of the alternate style names registered for this layer */
  public List<String> getOtherStyleNames() {
    if (layerInfo == null) {
      return Collections.emptyList();
    }
    final List<String> styleNames = new ArrayList<String>();

    for (StyleInfo si : layerInfo.getStyles()) {
      styleNames.add(si.getName());
    }
    return styleNames;
  }
Пример #3
0
  public void validate(LayerInfo lyr, boolean isNew) {
    if (lyr.isEnabled() == false) {
      // short-circuit - for disabled layers we don't need to validate
      // anything because it won't cause service exceptions for anyone
      return;
    }

    if (lyr.getResource() == null
        || (hasGeometry(lyr)
            && (lyr.getResource().getSRS() == null
                || lyr.getResource().getLatLonBoundingBox() == null)))
      throw new RuntimeException("Layer's resource is not fully configured");

    // Resource-dependent checks
    if (lyr.getType() == PublishedType.RASTER) {
      if (!(lyr.getResource() instanceof CoverageInfo))
        throw new RuntimeException("Layer with type RASTER doesn't have a coverage associated");
      CoverageInfo cvinfo = (CoverageInfo) lyr.getResource();
      try {
        cvinfo
            .getCatalog()
            .getResourcePool()
            .getGridCoverageReader(cvinfo, GeoTools.getDefaultHints());
      } catch (Throwable t) {
        throw new RuntimeException("Couldn't connect to raster layer's resource");
      }
    } else if (lyr.getType() == PublishedType.VECTOR) {
      if (!(lyr.getResource() instanceof FeatureTypeInfo))
        throw new RuntimeException("Layer with type VECTOR doesn't have a featuretype associated");
      FeatureTypeInfo ftinfo = (FeatureTypeInfo) lyr.getResource();
    } else throw new RuntimeException("Layer is neither RASTER nor VECTOR type");

    // Style-dependent checks
    if (hasGeometry(lyr) && (lyr.getDefaultStyle() == null || lyr.getStyles().contains(null)))
      throw new RuntimeException("Layer has null styles!");
  }
    /**
     * Calls super.handleFeatureType to add common FeatureType content such as Name, Title and
     * LatLonBoundingBox, and then writes WMS specific layer properties as Styles, Scale Hint, etc.
     *
     * @throws IOException
     * @task TODO: write wms specific elements.
     */
    @SuppressWarnings("deprecation")
    protected void handleLayer(final LayerInfo layer) {
      // HACK: by now all our layers are queryable, since they reference
      // only featuretypes managed by this server
      AttributesImpl qatts = new AttributesImpl();
      boolean queryable = wmsConfig.isQueryable(layer);
      qatts.addAttribute("", "queryable", "queryable", "", queryable ? "1" : "0");
      start("Layer", qatts);
      element("Name", layer.getResource().getNamespace().getPrefix() + ":" + layer.getName());
      // REVISIT: this is bad, layer should have title and anbstract by itself
      element("Title", layer.getResource().getTitle());
      element("Abstract", layer.getResource().getAbstract());
      handleKeywordList(layer.getResource().getKeywords());

      /**
       * @task REVISIT: should getSRS() return the full URL? no - the spec says it should be a set
       *     of <SRS>EPSG:#</SRS>...
       */
      final String srs = layer.getResource().getSRS();
      element("SRS", srs);

      // DJB: I want to be nice to the people reading the capabilities
      // file - I'm going to get the
      // human readable name and stick it in the capabilities file
      // NOTE: this isnt well done because "comment()" isnt in the
      // ContentHandler interface...
      try {
        CoordinateReferenceSystem crs = layer.getResource().getCRS();
        String desc = "WKT definition of this CRS:\n" + crs;
        comment(desc);
      } catch (Exception e) {
        if (LOGGER.isLoggable(Level.WARNING)) {
          LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e);
        }
      }

      Envelope bbox;
      try {
        bbox = layer.getResource().boundingBox();
      } catch (Exception e) {
        throw new RuntimeException(
            "Unexpected error obtaining bounding box for layer " + layer.getName(), e);
      }
      Envelope llbbox = layer.getResource().getLatLonBoundingBox();

      handleLatLonBBox(llbbox);
      // the native bbox might be null
      if (bbox != null) {
        handleBBox(bbox, srs);
      }

      // handle dimensions
      String timeMetadata = null;
      String elevationMetadata = null;

      if (layer.getType() == Type.VECTOR) {
        dimensionHelper.handleVectorLayerDimensions(layer);
      } else if (layer.getType() == Type.RASTER) {
        dimensionHelper.handleRasterLayerDimensions(layer);
      }

      // handle data attribution
      handleAttribution(layer);

      // handle metadata URLs
      handleMetadataList(layer.getResource().getMetadataLinks());

      if (layer.getResource() instanceof WMSLayerInfo) {
        // do nothing for the moment, we may want to list the set of cascaded named styles
        // in the future (when we add support for that)
      } else {
        // add the layer style
        start("Style");

        StyleInfo defaultStyle = layer.getDefaultStyle();
        if (defaultStyle == null) {
          throw new NullPointerException("Layer " + layer.getName() + " has no default style");
        }
        Style ftStyle;
        try {
          ftStyle = defaultStyle.getStyle();
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
        element("Name", defaultStyle.getName());
        element("Title", ftStyle.getTitle());
        element("Abstract", ftStyle.getAbstract());
        handleLegendURL(layer.getName(), layer.getLegend(), null);
        end("Style");

        Set<StyleInfo> styles = layer.getStyles();

        for (StyleInfo styleInfo : styles) {
          try {
            ftStyle = styleInfo.getStyle();
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
          start("Style");
          element("Name", styleInfo.getName());
          element("Title", ftStyle.getTitle());
          element("Abstract", ftStyle.getAbstract());
          handleLegendURL(layer.getName(), null, styleInfo);
          end("Style");
        }
      }

      end("Layer");
    }
  /**
   * Handles changes of interest to GWC on a {@link LayerInfo}.
   *
   * <ul>
   *   <li>If the name of the default style changed, then the layer's cache for the default style is
   *       truncated. This method doesn't check if the contents of the styles are equal. That is
   *       handled by {@link CatalogStyleChangeListener} whenever a style is modified.
   *   <li>If the tile layer is {@link GeoServerTileLayerInfo#isAutoCacheStyles() auto caching
   *       styles} and the layerinfo's "styles" list changed, the tile layer's STYLE parameter
   *       filter is updated to match the actual list of layer styles and any removed style is
   *       truncated.
   * </ul>
   *
   * @param changedProperties
   * @param oldValues
   * @param newValues
   * @param li
   * @param tileLayerInfo
   */
  private void handleLayerInfoChange(
      final List<String> changedProperties,
      final List<Object> oldValues,
      final List<Object> newValues,
      final LayerInfo li,
      final GeoServerTileLayerInfo tileLayerInfo) {

    checkNotNull(tileLayerInfo);

    final String layerName = tileLayerName(li);

    boolean save = false;

    final String defaultStyle;

    /*
     * If default style name changed
     */
    if (changedProperties.contains("defaultStyle")) {
      final int propIndex = changedProperties.indexOf("defaultStyle");
      final StyleInfo oldStyle = (StyleInfo) oldValues.get(propIndex);
      final StyleInfo newStyle = (StyleInfo) newValues.get(propIndex);

      final String oldStyleName = oldStyle.getName();
      defaultStyle = newStyle.getName();
      if (!Objects.equal(oldStyleName, defaultStyle)) {
        save = true;
        log.info(
            "Truncating default style for layer "
                + layerName
                + ", as it changed from "
                + oldStyleName
                + " to "
                + defaultStyle);
        mediator.truncateByLayerAndStyle(layerName, oldStyleName);
      }
    } else {
      StyleInfo styleInfo = li.getDefaultStyle();
      defaultStyle = styleInfo == null ? null : styleInfo.getName();
    }

    if (tileLayerInfo.isAutoCacheStyles()) {
      Set<String> styles = new HashSet<String>();
      for (StyleInfo s : li.getStyles()) {
        styles.add(s.getName());
      }
      ImmutableSet<String> cachedStyles = tileLayerInfo.cachedStyles();
      if (!styles.equals(cachedStyles)) {
        // truncate no longer existing cached styles
        Set<String> notCachedAnyMore = Sets.difference(cachedStyles, styles);
        for (String oldCachedStyle : notCachedAnyMore) {
          log.info(
              "Truncating cached style "
                  + oldCachedStyle
                  + " of layer "
                  + layerName
                  + " as it's no longer one of the layer's styles");
          mediator.truncateByLayerAndStyle(layerName, oldCachedStyle);
        }
        // reset STYLES parameter filter
        final boolean createParamIfNotExists = true;
        TileLayerInfoUtil.updateStringParameterFilter(
            tileLayerInfo, "STYLES", createParamIfNotExists, defaultStyle, styles);
        save = true;
      }
    }

    if (save) {
      GridSetBroker gridSetBroker = mediator.getGridSetBroker();
      GeoServerTileLayer tileLayer = new GeoServerTileLayer(li, gridSetBroker, tileLayerInfo);
      mediator.save(tileLayer);
    }
  }
Пример #6
0
  /**
   * Adds a vector layer to the catalog setup.
   *
   * <p>The layer is created within a store named <code>qName.getPrefix()</code>, creating it if it
   * does not exist. The resulting store is a {@link PropertyDataStore} that points at the directory
   * <code>getDataDirectoryRoot()/qName.getPrefix()</code>. Similarily the layer and store are
   * created within a workspace named <code>qName.getPrefix()</code>, which is created if it does
   * not already exist.
   *
   * <p>The properties data for the layer is copied from the classpath, with a file name of "<code>
   * filename</code>.properties". The <tt>scope</tt> parameter is used as the class from which to
   * load the properties file relative to.
   *
   * <p>The <tt>props</tt> parameter is used to define custom properties for the layer. See the
   * {@link LayerProperty} class for supported properties.
   */
  public void addVectorLayer(
      QName qName, Map<LayerProperty, Object> props, String filename, Class scope, Catalog catalog)
      throws IOException {
    String prefix = qName.getPrefix();
    String name = qName.getLocalPart();
    String uri = qName.getNamespaceURI();

    // configure workspace if it doesn;t already exist
    if (catalog.getWorkspaceByName(prefix) == null) {
      addWorkspace(prefix, uri, catalog);
    }

    // configure store if it doesn't already exist

    File storeDir = catalog.getResourceLoader().findOrCreateDirectory(prefix);

    DataStoreInfo store = catalog.getDataStoreByName(prefix);
    if (store == null) {
      store = catalog.getFactory().createDataStore();
      store.setName(prefix);
      store.setWorkspace(catalog.getWorkspaceByName(prefix));
      store.setEnabled(true);

      store.getConnectionParameters().put(PropertyDataStoreFactory.DIRECTORY.key, storeDir);
      store.getConnectionParameters().put(PropertyDataStoreFactory.NAMESPACE.key, uri);
      catalog.add(store);
    }

    // copy the properties file over

    catalog.getResourceLoader().copyFromClassPath(filename, new File(storeDir, filename), scope);

    // configure feature type
    FeatureTypeInfo featureType = catalog.getFactory().createFeatureType();
    featureType.setStore(store);
    featureType.setNamespace(catalog.getNamespaceByPrefix(prefix));
    featureType.setName(LayerProperty.NAME.get(props, name));
    featureType.setNativeName(FilenameUtils.getBaseName(filename));
    featureType.setTitle(name);
    featureType.setAbstract("abstract about " + name);

    Integer srs = LayerProperty.SRS.get(props, SRS.get(qName));
    if (srs == null) {
      srs = 4326;
    }
    featureType.setSRS("EPSG:" + srs);
    try {
      featureType.setNativeCRS(CRS.decode("EPSG:" + srs));
    } catch (Exception e) {
      LOGGER.warning("Failed to decode EPSG:" + srs + ", setting the native SRS to null");
    }
    featureType.setNumDecimals(8);
    featureType.getKeywords().add(new Keyword(name));
    featureType.setEnabled(true);
    featureType.setProjectionPolicy(
        LayerProperty.PROJECTION_POLICY.get(props, ProjectionPolicy.NONE));
    featureType.setLatLonBoundingBox(
        LayerProperty.LATLON_ENVELOPE.get(props, DEFAULT_LATLON_ENVELOPE));
    featureType.setNativeBoundingBox(LayerProperty.ENVELOPE.get(props, null));

    FeatureTypeInfo ft = catalog.getFeatureTypeByDataStore(store, name);
    LayerInfo layer = catalog.getLayerByName(new NameImpl(prefix, name));
    if (ft == null) {
      ft = featureType;
      catalog.add(featureType);
    } else {
      if (layer == null) {
        // handles the case of layer removed, but feature type not
        catalog.remove(ft);
        ft = featureType;
        catalog.add(featureType);
      } else {
        new CatalogBuilder(catalog).updateFeatureType(ft, featureType);
        catalog.save(ft);
      }
    }

    if (layer == null
        || !layer.getResource().getNamespace().equals(catalog.getNamespaceByPrefix(prefix))) {
      layer = catalog.getFactory().createLayer();
    }

    layer.setResource(ft);

    StyleInfo defaultStyle = null;
    if (LayerProperty.STYLE.get(props, null) != null) {
      defaultStyle = catalog.getStyleByName(LayerProperty.STYLE.get(props, null));
    } else {
      // look for a style matching the layer name
      defaultStyle = catalog.getStyleByName(name);
      if (defaultStyle == null) {
        // see if the resource exists and we just need to create it
        if (getClass().getResource(name + ".sld") != null) {
          addStyle(name, catalog);
          defaultStyle = catalog.getStyleByName(name);
        }
      }
    }

    if (defaultStyle == null) {
      defaultStyle = catalog.getStyleByName(DEFAULT_VECTOR_STYLE);
    }

    layer.getStyles().clear();
    layer.setDefaultStyle(defaultStyle);
    layer.setType(LayerInfo.Type.VECTOR);
    layer.setEnabled(true);

    if (layer.getId() == null) {
      catalog.add(layer);
    } else {
      catalog.save(layer);
    }
  }