proguard.util.WildcardManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proguard-core Show documentation
Show all versions of proguard-core Show documentation
ProGuardCORE is a free library to read, analyze, modify, and write Java class files.
/*
* ProGuardCORE -- library to process Java bytecode.
*
* Copyright (c) 2002-2020 Guardsquare NV
*
* 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 proguard.util;
import java.util.*;
/**
* This utility class creates and manages {@link StringMatcher} instances that
* (1) match wildcards, and
* (2) refer back to matched wildcards.
*
* Each instance represents a scope in which wildcards can be specified
* and referenced.
*
* @author Eric Lafortune
*/
public class WildcardManager
{
private List variableStringMatchers;
/**
* Creates a new WildcardManager.
*/
public WildcardManager()
{
this(new ArrayList());
}
/**
* Creates a new WildcardManager with the current list of string matchers
* of the given WildcardManager.
*/
public WildcardManager(WildcardManager wildcardManager)
{
this(new ArrayList(wildcardManager.variableStringMatchers));
}
/**
* Creates a new WildcardManager with the given list of string matchers.
*/
private WildcardManager(List variableStringMatchers)
{
this.variableStringMatchers = variableStringMatchers;
}
/**
* Resets the list of string matchers.
*/
public void reset()
{
variableStringMatchers.clear();
}
/**
* Creates a new VariableStringMatcher and remembers it as a next element
* in the list of string matchers, so it can be referenced by its index
* later.
*
* @param allowedCharacters an optional list of allowed characters.
* @param disallowedCharacters an optional list of disallowed characters.
* @param minimumLength the minimum length of te variable string.
* @param maximumLength the maximum length of te variable string.
* @param nextMatcher an optional next matcher for the remainder
* of the string.
*/
public VariableStringMatcher createVariableStringMatcher(char[] allowedCharacters,
char[] disallowedCharacters,
int minimumLength,
int maximumLength,
StringMatcher nextMatcher)
{
VariableStringMatcher variableStringMatcher =
new VariableStringMatcher(allowedCharacters,
disallowedCharacters,
minimumLength,
maximumLength,
nextMatcher);
rememberVariableStringMatcher(variableStringMatcher);;
return variableStringMatcher;
}
/**
* Remembers the given VariableStringMatcher as a next element in the list
* of string matchers, so it can be referenced by its index later.
*/
public void rememberVariableStringMatcher(VariableStringMatcher variableStringMatcher)
{
variableStringMatchers.add(variableStringMatcher);
}
/**
* Creates new MatchedStringMatcher to match the the specified variable
* string matcher from the list of string matchers.
*
* @param index the 0-based index of previously created and
* remembered VariableStringMatcher instances.
* @param nextMatcher an optional next matcher for the remainder of the
* string.
*/
public MatchedStringMatcher createMatchedStringMatcher(int index,
StringMatcher nextMatcher)
{
return new MatchedStringMatcher(variableStringMatchers.get(index),
nextMatcher);
}
/**
* Creates new StringFunction that transforms the given expression
* with possible references to wildcards, based on the list of
* string matchers.
*
* For example:
* "foo<1>" returns a string function that prepends "foo"
* to the first wildcard of the recently matched string.
*/
public StringFunction createMatchedStringFunction(String expression)
{
StringFunction stringFunction = null;
int prefixIndex = 0;
// Look for wildcards.
for (int index = 0; index < expression.length(); index++)
{
int wildCardIndex = wildCardIndex(expression, index);
if (wildCardIndex >= 0)
{
// Create the function for the matched wildcard.
StringFunction matchedStringFunction =
new MatchedStringFunction(variableStringMatchers.get(wildCardIndex));
// Prepend any skipped prefix.
StringFunction additionalStringFunction =
prefixIndex == index ?
matchedStringFunction :
new ConcatenatingStringFunction(new ConstantStringFunction(expression.substring(prefixIndex, index)), matchedStringFunction);
// Prepend any collected string function.
stringFunction =
stringFunction == null ?
additionalStringFunction :
new ConcatenatingStringFunction(stringFunction, additionalStringFunction);
// Find the index of the closing bracket again.
index = expression.indexOf('>', index + 1);
prefixIndex = index + 1;
}
}
// Make sure we have a function. Append any suffix.
return
stringFunction == null ? new ConstantStringFunction(expression) :
prefixIndex == expression.length() ? stringFunction :
new ConcatenatingStringFunction(stringFunction, new ConstantStringFunction(expression.substring(prefixIndex)));
}
/**
* Parses a reference to a wildcard at a given index, if any.
*
* For example:
* "foo<1>" at index 0 returns -1,
* "foo<1>" at index 3 returns 0.
* "foo<8>" at index 3 returns 7.
*
* @param regularExpression the regular expression.
* @param index the index at which the regular expression is
* to be checked for a reference.
* @return the 0-based index of the back reference, or -1 otherwise.
* @throws IllegalArgumentException if the reference is malformed.
*/
public int wildCardIndex(String regularExpression,
int index)
throws IllegalArgumentException
{
if (variableStringMatchers == null ||
regularExpression.charAt(index) != '<')
{
return -1;
}
int closingBracketIndex = regularExpression.indexOf('>', index);
if (closingBracketIndex < 0)
{
throw new IllegalArgumentException("Missing closing angular bracket after opening bracket at index "+index+" in ["+regularExpression+"]");
}
String argumentBetweenBrackets = regularExpression.substring(index+1, closingBracketIndex);
try
{
int wildcardIndex = Integer.parseInt(argumentBetweenBrackets);
if (wildcardIndex < 1 ||
wildcardIndex > variableStringMatchers.size())
{
throw new IllegalArgumentException("Invalid reference to wildcard ("+wildcardIndex+", must lie between 1 and "+variableStringMatchers.size()+" in ["+regularExpression+"])");
}
return wildcardIndex - 1;
}
catch (NumberFormatException e)
{
return -1;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy