Package org.springframework.xd.dirt.server.options

Source Code of org.springframework.xd.dirt.server.options.ResourcePatternScanningOptionHandler

/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.xd.dirt.server.options;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.NamedOptionDef;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

/**
* An {@link OptionHandler} that scans a resource pattern for existing resources (using a single '*' wildcard) and
* allows all String values <i>s</i> that would fit if that single wildcard was replaced by <i>s</i>.
*
* <p>
* Given that an option handler has to appear as an annotation parameter, expected usage is to sublcass this class,
* provide the canonical 3 arg constructor to {@link OptionHandler} and pass the resource pattern as the 4th argument.
* </p>
*
* @author Eric Bottard
*/
public abstract class ResourcePatternScanningOptionHandler extends OptionHandler<String> {

  private final Set<String> possibleValues = new HashSet<String>();

  private final Set<String> excluded = new HashSet<String>();

  protected ResourcePatternScanningOptionHandler(CmdLineParser parser, OptionDef option, Setter<String> setter,
      String glob)
      throws IOException {
    super(parser, option, setter);
    init(glob);
  }

  @Override
  public int parseArguments(Parameters params) throws CmdLineException {
    String s = params.getParameter(0);
    if (!possibleValues.contains(s)) {
      String errorMessage = String.format("'%s' is not a valid value. Possible values are %s", s, possibleValues);
      if (this.option instanceof NamedOptionDef) {
        NamedOptionDef named = (NamedOptionDef) this.option;
        errorMessage = String.format("'%s' is not a valid value for option %s. Possible values are %s", s,
            named.name(), possibleValues);
      }
      if (excluded.contains(s)) {
        errorMessage += String.format(
            ". Note that '%s' has been explicitly excluded from the list of possible values,"
                + " even though a resource with that name exists", s);
      }
      throw new CmdLineException(owner, errorMessage);
    }
    setter.addValue(s);
    return 1;
  }

  @Override
  public String getDefaultMetaVariable() {
    return possibleValues.toString().replace(",", " |");
  }

  private void init(String glob, String... excludes) throws IOException {
    String resolved = CommandLinePropertySourceOverridingListener.getCurrentEnvironment().resolvePlaceholders(glob);
    int protocolColon = resolved.indexOf(':');
    String withoutProtocol = protocolColon != -1 ? resolved.substring(protocolColon + 1) : resolved;
    Pattern capturing = Pattern.compile(".*" + withoutProtocol.replace("*", "([^/]*)") + ".*");

    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    for (Resource r : resolver.getResources(resolved)) {
      if (!shouldConsider(r)) {
        continue;
      }
      String path = r.getURL().toString();
      Matcher matcher = capturing.matcher(path);
      if (!matcher.matches()) {
        throw new IllegalStateException(
            String.format("Expected to match '%s' with regex '%s'", path, capturing));
      }
      possibleValues.add(matcher.group(1));
    }

  }

  /**
   * Whether the matched Spring resource should even be considered for inclusion in the result set.
   * Default implementation just returns true.
   */
  protected boolean shouldConsider(Resource r) {
    return true;
  }

  protected void exclude(String... excludes) {
    excluded.addAll(Arrays.asList(excludes));
    possibleValues.removeAll(excluded);
  }

  protected void include(String... includes) {
    possibleValues.addAll(Arrays.asList(includes));
  }

}
TOP

Related Classes of org.springframework.xd.dirt.server.options.ResourcePatternScanningOptionHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.