| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.wicket.util.parse.metapattern; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.wicket.util.io.IClusterable; |
| |
| |
| /** |
| * Useful class for constructing readable and reusable regular expressions. |
| * <p> |
| * MetaPatterns can be constructed from a simple regular expression String, from other MetaPatterns |
| * (copy constructor), from a list of MetaPatterns or from an array of MetaPatterns. In this way, it |
| * is easy to build up larger patterns while transparently binding the capturing groups of each |
| * MetaPattern for easy object oriented access to capturing group matches. |
| * <p> |
| * A given MetaPattern can be converted to a Matcher or Pattern. Groups within the MetaPattern can |
| * be used to automatically reference capturing group values when a match is made with a Matcher |
| * object. |
| * <p> |
| * A variety of static constants are provided for use in constructing compound MetaPatterns. Also, a |
| * number of simple parsers have been constructed using MetaPatterns in the parsers subpackage. |
| * |
| * @author Jonathan Locke |
| */ |
| public class MetaPattern implements IClusterable |
| { |
| private static final long serialVersionUID = 1L; |
| |
| /** |
| * Compiled regular expression pattern, or null if patterns variable is valid instead |
| */ |
| private Pattern pattern; |
| |
| /** List of patterns, or null if pattern variable is valid instead */ |
| private List<MetaPattern> patterns; |
| |
| /** The compiled MetaPattern */ |
| private Pattern compiledPattern; |
| |
| // Regexps that are used multiple times in defining meta patterns |
| private static final String _DOUBLE_QUOTED_STRING = "\"[^\"]*?\""; |
| private static final String _SINGLE_QUOTED_STRING = "'[^']*?\'"; |
| private static final String _STRING = "(?:[\\w\\-\\.]+|" + _DOUBLE_QUOTED_STRING + "|" + |
| _SINGLE_QUOTED_STRING + ")"; |
| private static final String _OPTIONAL_STRING = _STRING + "?"; |
| private static final String _VARIABLE_NAME = "[A-Za-z_][A-Za-z0-9_]*"; |
| private static final String _XML_NAME = "[A-Za-z_][A-Za-z0-9_.-]*"; |
| |
| // Delimiters and punctuation |
| /** Constant for whitespace. */ |
| public static final MetaPattern WHITESPACE = new MetaPattern("\\s+"); |
| |
| /** Constant for optional whitespace. */ |
| public static final MetaPattern OPTIONAL_WHITESPACE = new MetaPattern("\\s*"); |
| |
| /** Constant for non-word. */ |
| public static final MetaPattern NON_WORD = new MetaPattern("\\W+"); |
| |
| /** Constant for comma. */ |
| public static final MetaPattern COMMA = new MetaPattern(","); |
| |
| /** Constant for colon. */ |
| public static final MetaPattern COLON = new MetaPattern(":"); |
| |
| /** Constant for semicolon. */ |
| public static final MetaPattern SEMICOLON = new MetaPattern(";"); |
| |
| /** Constant for slash. */ |
| public static final MetaPattern SLASH = new MetaPattern("/"); |
| |
| /** Constant for backslash. */ |
| public static final MetaPattern BACKSLASH = new MetaPattern("\\\\"); |
| |
| /** Constant for dot. */ |
| public static final MetaPattern DOT = new MetaPattern("\\."); |
| |
| /** Constant for plus. */ |
| public static final MetaPattern PLUS = new MetaPattern("\\+"); |
| |
| /** Constant for minus. */ |
| public static final MetaPattern MINUS = new MetaPattern("-"); |
| |
| /** Constant for dash. */ |
| public static final MetaPattern DASH = new MetaPattern("-"); |
| |
| /** Constant for underscore. */ |
| public static final MetaPattern UNDERSCORE = new MetaPattern("_"); |
| |
| /** Constant for ampersand. */ |
| public static final MetaPattern AMPERSAND = new MetaPattern("&"); |
| |
| /** Constant for percent. */ |
| public static final MetaPattern PERCENT = new MetaPattern("%"); |
| |
| /** Constant for dollar. */ |
| public static final MetaPattern DOLLAR_SIGN = new MetaPattern("$"); |
| |
| /** Constant for pound. */ |
| public static final MetaPattern POUND_SIGN = new MetaPattern("#"); |
| |
| /** Constant for at. */ |
| public static final MetaPattern AT_SIGN = new MetaPattern("@"); |
| |
| /** Constant for excl. */ |
| public static final MetaPattern EXCLAMATION_POINT = new MetaPattern("!"); |
| |
| /** Constant for tilde. */ |
| public static final MetaPattern TILDE = new MetaPattern("~"); |
| |
| /** Constant for equals. */ |
| public static final MetaPattern EQUALS = new MetaPattern("="); |
| |
| /** Constant for star. */ |
| public static final MetaPattern STAR = new MetaPattern("\\*"); |
| |
| /** Constant for pipe. */ |
| public static final MetaPattern PIPE = new MetaPattern("\\|"); |
| |
| /** Constant for left paren. */ |
| public static final MetaPattern LEFT_PAREN = new MetaPattern("\\("); |
| |
| /** Constant for right paren. */ |
| public static final MetaPattern RIGHT_PAREN = new MetaPattern("\\)"); |
| |
| /** Constant for left curly braces. */ |
| public static final MetaPattern LEFT_CURLY = new MetaPattern("\\{"); |
| |
| /** Constant for right curly braces. */ |
| public static final MetaPattern RIGHT_CURLY = new MetaPattern("\\}"); |
| |
| /** Constant for left square bracket. */ |
| public static final MetaPattern LEFT_SQUARE = new MetaPattern("\\["); |
| |
| /** Constant for right square bracket. */ |
| public static final MetaPattern RIGHT_SQUARE = new MetaPattern("\\]"); |
| |
| /** Constant for digit. */ |
| public static final MetaPattern DIGIT = new MetaPattern("\\d"); |
| |
| /** Constant for digits. */ |
| public static final MetaPattern DIGITS = new MetaPattern("\\d+"); |
| |
| /** Constant for an integer (of any size). */ |
| public static final MetaPattern INTEGER = new MetaPattern("-?\\d+"); |
| |
| /** Constant for a floating point number. */ |
| public static final MetaPattern FLOATING_POINT_NUMBER = new MetaPattern( |
| "-?\\d+\\.?\\d*|-?\\.\\d+"); |
| |
| /** Constant for a positive integer. */ |
| public static final MetaPattern POSITIVE_INTEGER = new MetaPattern("\\d+"); |
| |
| /** Constant for hex digit. */ |
| public static final MetaPattern HEXADECIMAL_DIGIT = new MetaPattern("[0-9a-fA-F]"); |
| |
| /** Constant for hex digits. */ |
| public static final MetaPattern HEXADECIMAL_DIGITS = new MetaPattern("[0-9a-fA-F]+"); |
| |
| /** Constant for anything (string). */ |
| public static final MetaPattern ANYTHING = new MetaPattern(".*"); |
| |
| /** Constant for anything non-empty (string). */ |
| public static final MetaPattern ANYTHING_NON_EMPTY = new MetaPattern(".+"); |
| |
| /** Constant for a word. */ |
| public static final MetaPattern WORD = new MetaPattern("\\w+"); |
| |
| /** Constant for an optional word. */ |
| public static final MetaPattern OPTIONAL_WORD = new MetaPattern("\\w*"); |
| |
| /** Constant for a variable name. */ |
| public static final MetaPattern VARIABLE_NAME = new MetaPattern(_VARIABLE_NAME); |
| |
| /** Constant for an XML element name. */ |
| public static final MetaPattern XML_ELEMENT_NAME = new MetaPattern(_XML_NAME); |
| |
| /** Constant for an XML attribute name. */ |
| public static final MetaPattern XML_ATTRIBUTE_NAME = new MetaPattern(_XML_NAME); |
| |
| /** Constant for perl interpolation. */ |
| public static final MetaPattern PERL_INTERPOLATION = new MetaPattern("$\\{" + _VARIABLE_NAME + |
| "\\}"); |
| |
| /** Constant for a double quoted string. */ |
| public static final MetaPattern DOUBLE_QUOTED_STRING = new MetaPattern(_DOUBLE_QUOTED_STRING); |
| |
| /** Constant for a string. */ |
| public static final MetaPattern STRING = new MetaPattern(_STRING); |
| |
| /** Constant for an optional string. */ |
| public static final MetaPattern OPTIONAL_STRING = new MetaPattern(_OPTIONAL_STRING); |
| |
| /** |
| * Constructor for a simple pattern. |
| * |
| * @param pattern |
| * The regular expression pattern to compile |
| */ |
| public MetaPattern(final String pattern) |
| { |
| this.pattern = Pattern.compile(pattern); |
| } |
| |
| /** |
| * Copy constructor. |
| * |
| * @param pattern |
| * The meta pattern to copy |
| */ |
| public MetaPattern(final MetaPattern pattern) |
| { |
| this.pattern = pattern.pattern; |
| patterns = pattern.patterns; |
| compiledPattern = pattern.compiledPattern; |
| } |
| |
| /** |
| * Constructs from an array of MetaPatterns. |
| * |
| * @param patterns |
| * Array of MetaPatterns |
| */ |
| public MetaPattern(final MetaPattern... patterns) |
| { |
| this(Arrays.asList(patterns)); |
| } |
| |
| /** |
| * Constructs from a list of MetaPatterns |
| * |
| * @param patterns |
| * List of MetaPatterns |
| */ |
| public MetaPattern(final List<MetaPattern> patterns) |
| { |
| this.patterns = patterns; |
| } |
| |
| /** |
| * Creates a matcher against a given input character sequence. |
| * |
| * @param input |
| * The input to match against |
| * @return The matcher |
| */ |
| public final Matcher matcher(final CharSequence input) |
| { |
| return matcher(input, 0); |
| } |
| |
| /** |
| * Creates a matcher with the given regexp compile flags. Once you call this method with a given |
| * regexp compile flag value, the pattern will be compiled. Calling it again with a different |
| * value for flags will not recompile the pattern. |
| * |
| * @param input |
| * The input to match |
| * @param flags |
| * One or more of the standard Java regular expression compile flags (see |
| * {@link Pattern#compile(String, int)}) |
| * @return The matcher |
| */ |
| public final Matcher matcher(final CharSequence input, final int flags) |
| { |
| compile(flags); |
| return compiledPattern.matcher(input); |
| } |
| |
| /** |
| * Gets the regular expression Pattern for this MetaPattern by compiling it. |
| * |
| * @return Pattern compiled with default Java regular expression compile flags |
| */ |
| public final Pattern pattern() |
| { |
| return pattern(0); |
| } |
| |
| /** |
| * Gets the regular expression Pattern for this MetaPattern by compiling it using the given |
| * flags. |
| * |
| * @param flags |
| * One or more of the standard Java regular expression compile flags (see |
| * {@link Pattern#compile(String, int)}) |
| * @return Equivalent Java regular expression Pattern compiled with the given flags |
| */ |
| public final Pattern pattern(final int flags) |
| { |
| compile(flags); |
| return compiledPattern; |
| } |
| |
| /** |
| * Converts this MetaPattern to a String. |
| * |
| * @return A String representing this MetaPattern |
| * @see java.lang.Object#toString() |
| */ |
| @Override |
| public String toString() |
| { |
| if (pattern != null) |
| { |
| return pattern.pattern(); |
| } |
| else |
| { |
| final StringBuilder buffer = new StringBuilder(); |
| for (MetaPattern metaPattern : patterns) |
| { |
| buffer.append(metaPattern); |
| } |
| return buffer.toString(); |
| } |
| } |
| |
| /** |
| * Compiles this MetaPattern with the given Java regular expression flags. |
| * |
| * @param flags |
| * One or more of the standard Java regular expression compile flags (see |
| * {@link Pattern#compile(String, int)}) |
| */ |
| private synchronized void compile(final int flags) |
| { |
| if (compiledPattern == null) |
| { |
| bind(1); |
| compiledPattern = Pattern.compile(toString(), flags); |
| } |
| } |
| |
| /** |
| * Binds this MetaPattern to one or more capturing groups. Since MetaPatterns can nest, the |
| * binding process can recurse. |
| * |
| * @param group |
| * The initial capturing group number |
| * @return The final capturing group (for use in recursion) |
| */ |
| private int bind(int group) |
| { |
| if (this instanceof Group) |
| { |
| ((Group)this).bind(group++); |
| } |
| |
| if (patterns != null) |
| { |
| for (MetaPattern metaPattern : patterns) |
| { |
| group = metaPattern.bind(group); |
| } |
| } |
| |
| return group; |
| } |
| } |