All Downloads are FREE. Search and download functionalities are using the official Maven repository.

proguard.util.WildcardManager Maven / Gradle / Ivy

Go to download

ProGuardCORE is a free library to read, analyze, modify, and write Java class files.

There is a newer version: 9.1.6
Show newest version
/*
 * 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.ArrayList;
import java.util.List;
import proguard.exception.ErrorId;
import proguard.exception.ProguardCoreException;

/**
 * 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 (variableStringMatchers.isEmpty()) { throw new ProguardCoreException( ErrorId.WILDCARD_WRONG_INDEX, "Reference to wildcard %d in expression %s but no matched groups to refer to.", wildcardIndex, regularExpression); } else if (wildcardIndex > variableStringMatchers.size()) { throw new ProguardCoreException( ErrorId.WILDCARD_WRONG_INDEX, "Invalid Reference to wildcard (%d, must lie between 1 and %d in [%s])", wildcardIndex, variableStringMatchers.size(), regularExpression); } return wildcardIndex - 1; } catch (NumberFormatException e) { return -1; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy