public static void addAutoStyleParameterFilter(
     final LayerInfo layer, GeoServerTileLayerInfo layerInfo) {
   StyleParameterFilter filter = new StyleParameterFilter();
   filter.setLayer(layer);
   layerInfo.removeParameterFilter("STYLES");
   layerInfo.getParameterFilters().add(filter);
 }
  /**
   * Set the styles which should be cached on a layer
   *
   * @param info
   * @param defaultStyle
   * @param cachedStyles
   */
  public static void setCachedStyles(
      GeoServerTileLayerInfo info, String defaultStyle, Set<String> cachedStyles) {
    StyleParameterFilter filter = (StyleParameterFilter) info.getParameterFilter("STYLES");
    if (filter == null) filter = new StyleParameterFilter();

    filter.setDefaultValue(defaultStyle);
    filter.setStyles(cachedStyles);
    info.addParameterFilter(filter);
  }
  /**
   * If the layer is configured for automatic style updates of its Style parameter filter, do so.
   *
   * @param layer The GeoServer layer group
   * @param layerInfo The GeoWebCache layer
   */
  public static void checkAutomaticStyles(
      final LayerGroupInfo layer, GeoServerTileLayerInfo layerInfo) {

    ParameterFilter filter = layerInfo.getParameterFilter("STYLES");

    // Remove the filter as groups shouldn't have auto-updating styles
    if (filter != null && filter instanceof StyleParameterFilter) {
      layerInfo.removeParameterFilter("STYLES");
    }
  }
  /**
   * Saves a tile layer info into the given metadata map using the old legacy metadata elements. For
   * unit testing only.
   *
   * @param source
   * @param metadata
   */
  public static void save(GeoServerTileLayerInfo source, MetadataMap metadata) {
    final boolean enabled = source.isEnabled();
    final int gutter = source.getGutter();
    final Set<XMLGridSubset> cachedGridSubsets = source.getGridSubsets();
    final int metaTilingX = source.getMetaTilingX();
    final int metaTilingY = source.getMetaTilingY();
    final Set<String> mimeFormats = source.getMimeFormats();
    final Boolean autoCacheStyles = source.isAutoCacheStyles();
    final Set<String> cachedStyles = source.cachedStyles();
    final boolean inMemoryCached = source.isInMemoryCached();

    metadata.put(CONFIG_KEY_ENABLED, Boolean.valueOf(enabled));
    metadata.put(CONFIG_KEY_GUTTER, Integer.valueOf(gutter));
    Collection<String> subsetNames = new ArrayList<String>();
    for (XMLGridSubset s : cachedGridSubsets) {
      subsetNames.add(s.getGridSetName());
    }
    metadata.put(CONFIG_KEY_GRIDSETS, marshalList(subsetNames));
    metadata.put(CONFIG_KEY_METATILING_X, Integer.valueOf(metaTilingX));
    metadata.put(CONFIG_KEY_METATILING_Y, Integer.valueOf(metaTilingY));
    metadata.put(CONFIG_KEY_FORMATS, marshalList(mimeFormats));
    metadata.put(CONFIG_KEY_AUTO_CACHE_STYLES, autoCacheStyles);
    metadata.put(CONFIG_KEY_IN_MEMORY_CACHED, inMemoryCached);

    if (cachedStyles.size() > 0) {
      metadata.put(CONFIG_KEY_CACHED_STYLES, marshalList(cachedStyles));
    } else {
      metadata.remove(CONFIG_KEY_CACHED_STYLES);
    }
  }
  /**
   * Add a {@link FloatParameterFilter} set accept anything, replacing any existing filter for the
   * same parameter.
   *
   * @param tileLayerInfo layer to update the filter on
   * @param paramKey key for the parameter
   * @param createParam create a new filter if there is none to replace for the specified key
   */
  public static void updateAcceptAllFloatParameterFilter(
      final GeoServerTileLayerInfo tileLayerInfo, final String paramKey, boolean createParam) {

    createParam |= tileLayerInfo.removeParameterFilter(paramKey);

    if (createParam) {
      FloatParameterFilter filter = new FloatParameterFilter();
      filter.setKey(paramKey);
      filter.setDefaultValue("");
      tileLayerInfo.addParameterFilter(filter);
    }
  }
  public void testLoadLayerInfo() {
    LayerInfoImpl layer = mockLayer("testLayer");

    assertNull(LegacyTileLayerInfoLoader.load(layer));

    LegacyTileLayerInfoLoader.save(defaultVectorInfo, layer.getMetadata());

    GeoServerTileLayerInfo info2 = LegacyTileLayerInfoLoader.load(layer);

    defaultVectorInfo.setId(layer.getId());
    defaultVectorInfo.setName(tileLayerName(layer));
    assertEquals(defaultVectorInfo, info2);
  }
 @Override
 public void setUp() {
   defaults = GWCConfig.getOldDefaults();
   defaultVectorInfo = TileLayerInfoUtil.create(defaults);
   defaultVectorInfo.getMimeFormats().clear();
   defaultVectorInfo.getMimeFormats().addAll(defaults.getDefaultVectorCacheFormats());
 }
  public void testLoadLayerGroup() {
    LayerGroupInfoImpl lg = mockGroup("tesGroup", mockLayer("L1"), mockLayer("L2"));

    assertNull(LegacyTileLayerInfoLoader.load(lg));
    GeoServerTileLayerInfo info = defaultVectorInfo;
    info.getMimeFormats().clear();
    info.getMimeFormats().addAll(defaults.getDefaultOtherCacheFormats());

    LegacyTileLayerInfoLoader.save(info, lg.getMetadata());

    GeoServerTileLayerInfo actual;
    actual = LegacyTileLayerInfoLoader.load(lg);

    info.setId(lg.getId());
    info.setName(GWC.tileLayerName(lg));
    assertEquals(info, actual);
  }
  /**
   * If the layer is configured for automatic style updates of its Style parameter filter, do so.
   *
   * @param layer The GeoServer layer
   * @param layerInfo The GeoWebCache layer
   */
  public static void checkAutomaticStyles(final LayerInfo layer, GeoServerTileLayerInfo layerInfo) {

    ParameterFilter filter = layerInfo.getParameterFilter("STYLES");

    // Update the filter with the latest available styles if it's a style filter
    if (filter != null && filter instanceof StyleParameterFilter) {
      ((StyleParameterFilter) filter).setLayer(layer);
    }
  }
  /**
   * Add a {@link StringParameterFilter} to the layer, replacing any existing filter for the same
   * parameter.
   *
   * @param tileLayerInfo layer to update the filter on
   * @param paramKey key for the parameter
   * @param createParam create a new filter if there is none to replace for the specified key
   * @param defaultValue default value
   * @param allowedValues legal values for the parameter
   */
  public static void updateStringParameterFilter(
      final GeoServerTileLayerInfo tileLayerInfo,
      final String paramKey,
      boolean createParam,
      final String defaultValue,
      final Set<String> allowedValues) {

    createParam |= tileLayerInfo.removeParameterFilter(paramKey);

    if (createParam && allowedValues != null && allowedValues.size() > 0) {
      // make sure default value is among the list of allowed values
      Set<String> values = new TreeSet<String>(allowedValues);

      StringParameterFilter stringListFilter = new StringParameterFilter();
      stringListFilter.setKey(paramKey);
      stringListFilter.setDefaultValue(defaultValue == null ? "" : defaultValue);
      values.addAll(stringListFilter.getValues());
      stringListFilter.setValues(new ArrayList<String>(values));
      tileLayerInfo.addParameterFilter(stringListFilter);
    }
  }
  public void testLoadLayerInfoAutoCacheStyles() {
    GeoServerTileLayerInfo info = defaultVectorInfo;
    info.setAutoCacheStyles(true);

    LayerInfoImpl layer = mockLayer("testLayer", "style1", "style2");
    assertNull(LegacyTileLayerInfoLoader.load(layer));

    LegacyTileLayerInfoLoader.save(info, layer.getMetadata());

    GeoServerTileLayerInfo actual;
    actual = LegacyTileLayerInfoLoader.load(layer);

    TileLayerInfoUtil.setCachedStyles(info, "default", ImmutableSet.of("style1", "style2"));

    info.setId(layer.getId());
    info.setName(tileLayerName(layer));
    assertEquals(info, actual);

    layer.setDefaultStyle(null);
    TileLayerInfoUtil.setCachedStyles(info, null, ImmutableSet.of("style1", "style2"));

    actual = LegacyTileLayerInfoLoader.load(layer);
    assertEquals(ImmutableSet.of("style1", "style2"), actual.cachedStyles());
  }
 /**
  * Remove a parameter filter from a layer
  *
  * @param tileLayerInfo the layer
  * @param paramKey the key of the parameter filter
  * @return true if a parameter matched and was removed, false otherwise
  * @deprecated
  */
 public static boolean removeParameterFilter(
     final GeoServerTileLayerInfo tileLayerInfo, final String paramKey) {
   return tileLayerInfo.removeParameterFilter(paramKey);
 }
  private void handleRename(
      final GeoServerTileLayerInfo tileLayerInfo,
      final CatalogInfo source,
      final List<String> changedProperties,
      final List<Object> oldValues,
      final List<Object> newValues) {

    final int nameIndex = changedProperties.indexOf("name");
    final int namespaceIndex = changedProperties.indexOf("namespace");

    String oldLayerName;
    String newLayerName;
    if (source instanceof ResourceInfo) { // covers LayerInfo, CoverageInfo, and WMSLayerInfo
      // must cover prefix:name
      final ResourceInfo resourceInfo = (ResourceInfo) source;
      final NamespaceInfo currNamespace = resourceInfo.getNamespace();
      final NamespaceInfo oldNamespace;
      if (namespaceIndex > -1) {
        // namespace changed
        oldNamespace = (NamespaceInfo) oldValues.get(namespaceIndex);
      } else {
        oldNamespace = currNamespace;
      }

      newLayerName = resourceInfo.prefixedName();
      if (nameIndex > -1) {
        oldLayerName = (String) oldValues.get(nameIndex);
      } else {
        oldLayerName = resourceInfo.getName();
      }
      oldLayerName = oldNamespace.getPrefix() + ":" + oldLayerName;
    } else {
      // it's a layer group, no need to worry about namespace
      oldLayerName = tileLayerInfo.getName();
      newLayerName = tileLayerName((LayerGroupInfo) source);
    }

    if (!oldLayerName.equals(newLayerName)) {
      tileLayerInfo.setName(newLayerName);

      // notify the mediator of the rename so it changes the name of the layer in GWC without
      // affecting its caches
      GridSetBroker gridSetBroker = mediator.getGridSetBroker();

      final GeoServerTileLayer oldTileLayer =
          (GeoServerTileLayer) mediator.getTileLayerByName(oldLayerName);

      checkState(
          null != oldTileLayer,
          "hanldeRename: old tile layer not found: '"
              + oldLayerName
              + "'. New name: '"
              + newLayerName
              + "'");

      final GeoServerTileLayer modifiedTileLayer;

      if (oldTileLayer.getLayerInfo() != null) {
        LayerInfo layerInfo = oldTileLayer.getLayerInfo();
        modifiedTileLayer = new GeoServerTileLayer(layerInfo, gridSetBroker, tileLayerInfo);
      } else {
        LayerGroupInfo layerGroup = oldTileLayer.getLayerGroupInfo();
        modifiedTileLayer = new GeoServerTileLayer(layerGroup, gridSetBroker, tileLayerInfo);
      }
      mediator.save(modifiedTileLayer);
    }
  }
  /**
   * 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);
    }
  }