From ac68a31c362b11abaa80164082341f4cda011c02 Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Tue, 20 Oct 2009 21:10:20 +0200 Subject: [PATCH] Some minor clean-up before release. - Removing some deprecated stuff - Moving unused classes to sandbox --- .../java/com/twelvemonkeys/io/FileUtil.java | 2 +- .../twelvemonkeys/io/FilenameMaskFilter.java | 4 +- .../twelvemonkeys/io/StringArrayReader.java | 2 +- .../util/regex/WildcardStringParser.java | 1384 ++++++++--------- twelvemonkeys-imageio/jmagick/pom.xml | 4 +- .../imageio/plugins/pict/QDTest.java | 35 +- .../twelvemonkeys/image/ConvolveTester.java | 0 .../com/twelvemonkeys/image/EasyImage.java | 0 .../image/ExtendedImageConsumer.java | 0 .../twelvemonkeys/image/SubsampleTester.java | 0 .../com/twelvemonkeys/lang/NativeLoader.java | 0 .../twelvemonkeys/lang/NativeResourceSPI.java | 0 .../com/twelvemonkeys/util/DebugUtil.java | 0 .../util/regex/REWildcardStringParser.java | 0 .../twelvemonkeys/servlet/ServletUtil.java | 10 +- 15 files changed, 726 insertions(+), 715 deletions(-) mode change 100755 => 100644 twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/QDTest.java rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/image/ConvolveTester.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/image/EasyImage.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/image/SubsampleTester.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/lang/NativeLoader.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/util/DebugUtil.java (100%) rename {twelvemonkeys-core => twelvemonkeys-sandbox}/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java (100%) diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FileUtil.java b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FileUtil.java index defb8d04..1e16c2a0 100755 --- a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FileUtil.java +++ b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FileUtil.java @@ -878,7 +878,7 @@ public final class FileUtil { File folder = resolve(pFolder); if (!(/*folder.exists() &&*/folder.isDirectory() && folder.canRead())) { - // NOTE: exists is implictly called by isDirectory + // NOTE: exists is implicitly called by isDirectory throw new FileNotFoundException("\"" + pFolder + "\" is not a directory or is not readable."); } diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FilenameMaskFilter.java b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FilenameMaskFilter.java index 1626affc..ed3cd477 100755 --- a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FilenameMaskFilter.java +++ b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/FilenameMaskFilter.java @@ -156,8 +156,8 @@ public class FilenameMaskFilter implements FilenameFilter { * This method implements the {@code java.io.FilenameFilter} interface. * * @param pDir the directory in which the file was found. - * @param pName the pName of the file. - * @return {@code true} if the pName should be included in the file + * @param pName the name of the file. + * @return {@code true} if the file {@code pName} should be included in the file * list; {@code false} otherwise. */ public boolean accept(File pDir, String pName) { diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/StringArrayReader.java b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/StringArrayReader.java index 8f2dbb55..27d59d89 100755 --- a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/StringArrayReader.java +++ b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/StringArrayReader.java @@ -53,7 +53,7 @@ public class StringArrayReader extends StringReader { /** * Create a new string array reader. * - * @param pStrings Strings providing the character stream. + * @param pStrings {@code String}s providing the character stream. */ public StringArrayReader(final String[] pStrings) { super(""); diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/WildcardStringParser.java b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/WildcardStringParser.java index a58d47b6..62dbeb5f 100755 --- a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/WildcardStringParser.java +++ b/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/WildcardStringParser.java @@ -28,73 +28,71 @@ package com.twelvemonkeys.util.regex; -import com.twelvemonkeys.util.DebugUtil; - import java.io.PrintStream; /** * This class parses arbitrary strings against a wildcard string mask provided. * The wildcard characters are '*' and '?'. - *

+ *

* The string masks provided are treated as case sensitive.
* Null-valued string masks as well as null valued strings to be parsed, will lead to rejection. - * - *

- * + *

+ *

+ *

* This class is custom designed for wildcard string parsing and is several times faster than the implementation based on the Jakarta Regexp package. - * + *

*


- * + *

* This task is performed based on regular expression techniques. * The possibilities of string generation with the well-known wildcard characters stated above, - * represent a subset of the possibilities of string generation with regular expressions.
+ * represent a subset of the possibilities of string generation with regular expressions.
* The '*' corresponds to ([Union of all characters in the alphabet])*
* The '?' corresponds to ([Union of all characters in the alphabet])
*       These expressions are not suited for textual representation at all, I must say. Is there any math tags included in HTML? - * - *

- * + *

+ *

+ *

* The complete meta-language for regular expressions are much larger. * This fact makes it fairly straightforward to build data structures for parsing because the amount of rules of building these structures are quite limited, as stated below. - * - *

- * + *

+ *

+ *

* To bring this over to mathematical terms: * The parser ia a nondeterministic finite automaton (latin) representing the grammar which is stated by the string mask. * The language accepted by this automaton is the set of all strings accepted by this automaton.
* The formal automaton quintuple consists of: *

    - *
  1. A finite set of states, depending on the wildcard string mask. - * For each character in the mask a state representing that character is created. - * The number of states therefore coincides with the length of the mask. - *
  2. An alphabet consisting of all legal filename characters - included the two wildcard characters '*' and '?'. - * This alphabet is hard-coded in this class. It contains {a .. å}, {A .. Å}, {0 .. 9}, {.}, {_}, {-}, {*} and {?}. - *
  3. A finite set of initial states, here only consisting of the state corresponding to the first character in the mask. - *
  4. A finite set of final states, here only consisting of the state corresponding to the last character in the mask. - *
  5. A transition relation that is a finite set of transitions satisfying some formal rules.
    - * This implementation on the other hand, only uses ad-hoc rules which start with an initial setup of the states as a sequence according to the string mask.
    - * Additionally, the following rules completes the building of the automaton: - *
      - *
    1. If the next state represents the same character as the next character in the string to test - go to this next state. - *
    2. If the next state represents '*' - go to this next state. - *
    3. If the next state represents '?' - go to this next state. - *
    4. If a '*' is followed by one or more '?', the last of these '?' state counts as a '*' state. Some extra checks regarding the number of characters read must be imposed if this is the case... - *
    5. If the next character in the string to test does not coincide with the next state - go to the last state representing '*'. If there are none - rejection. - *
    6. If there are no subsequent state (final state) and the state represents '*' - acceptance. - *
    7. If there are no subsequent state (final state) and the end of the string to test is reached - acceptance. - *
    - *
    - * - * Disclaimer: This class does not build a finite automaton according to formal mathematical rules. - * The proper way of implementation should be finding the complete set of transition relations, decomposing these into rules accepted by a deterministic finite automaton and finally build this automaton to be used for string parsing. - * Instead, this class is ad-hoc implemented based on the informal transition rules stated above. - * Therefore the correctness cannot be guaranteed before extensive testing has been imposed on this class... anyway, I think I have succeeded. - * Parsing faults must be reported to the author. - * + *
  6. A finite set of states, depending on the wildcard string mask. + * For each character in the mask a state representing that character is created. + * The number of states therefore coincides with the length of the mask. + *
  7. An alphabet consisting of all legal filename characters - included the two wildcard characters '*' and '?'. + * This alphabet is hard-coded in this class. It contains {a .. å}, {A .. Å}, {0 .. 9}, {.}, {_}, {-}, {*} and {?}. + *
  8. A finite set of initial states, here only consisting of the state corresponding to the first character in the mask. + *
  9. A finite set of final states, here only consisting of the state corresponding to the last character in the mask. + *
  10. A transition relation that is a finite set of transitions satisfying some formal rules.
    + * This implementation on the other hand, only uses ad-hoc rules which start with an initial setup of the states as a sequence according to the string mask.
    + * Additionally, the following rules completes the building of the automaton: + *
      + *
    1. If the next state represents the same character as the next character in the string to test - go to this next state. + *
    2. If the next state represents '*' - go to this next state. + *
    3. If the next state represents '?' - go to this next state. + *
    4. If a '*' is followed by one or more '?', the last of these '?' state counts as a '*' state. Some extra checks regarding the number of characters read must be imposed if this is the case... + *
    5. If the next character in the string to test does not coincide with the next state - go to the last state representing '*'. If there are none - rejection. + *
    6. If there are no subsequent state (final state) and the state represents '*' - acceptance. + *
    7. If there are no subsequent state (final state) and the end of the string to test is reached - acceptance. *
    - * + *
    + * + * Disclaimer: This class does not build a finite automaton according to formal mathematical rules. + * The proper way of implementation should be finding the complete set of transition relations, decomposing these into rules accepted by a deterministic finite automaton and finally build this automaton to be used for string parsing. + * Instead, this class is ad-hoc implemented based on the informal transition rules stated above. + * Therefore the correctness cannot be guaranteed before extensive testing has been imposed on this class... anyway, I think I have succeeded. + * Parsing faults must be reported to the author. + * + *
+ *

*


- * + *

* Examples of usage:
* This example will return "Accepted!". *

@@ -105,695 +103,677 @@ import java.io.PrintStream;
  *     System.out.println("Not accepted!");
  * }
  * 
- * + *

*


- * + *

* Theories and concepts are based on the book Elements of the Theory of Computation, by Harry l. Lewis and Christos H. Papadimitriou, (c) 1981 by Prentice Hall. + *

+ *

* - *

* @author Eirik Torske - * @see com.twelvemonkeys.util.regex.REWildcardStringParser + * @deprecated Will probably be removed in the near future */ public class WildcardStringParser { - // Constants - - /** Field ALPHABET */ - public static final char[] ALPHABET = { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'æ', - 'ø', 'å', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'N', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', 'Æ', 'Ø', 'Å', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' - }; - - /** Field FREE_RANGE_CHARACTER */ - public static final char FREE_RANGE_CHARACTER = '*'; - - /** Field FREE_PASS_CHARACTER */ - public static final char FREE_PASS_CHARACTER = '?'; - - // Members - boolean mInitialized; - String mStringMask; - WildcardStringParserState mInitialState; - int mTotalNumberOfStringsParsed; - boolean mDebugging; - PrintStream out; - - // Properties - // Constructors - - /** - * Creates a wildcard string parser. - *

- * @param pStringMask the wildcard string mask. - */ - public WildcardStringParser(final String pStringMask) { - this(pStringMask, false); - } - - /** - * Creates a wildcard string parser. - *

- * @param pStringMask the wildcard string mask. - * @param pDebugging {@code true} will cause debug messages to be emitted to {@code System.out}. - */ - public WildcardStringParser(final String pStringMask, final boolean pDebugging) { - this(pStringMask, pDebugging, System.out); - } - - /** - * Creates a wildcard string parser. - *

- * @param pStringMask the wildcard string mask. - * @param pDebugging {@code true} will cause debug messages to be emitted. - * @param pDebuggingPrintStream the {@code java.io.PrintStream} to which the debug messages will be emitted. - */ - public WildcardStringParser(final String pStringMask, final boolean pDebugging, final PrintStream pDebuggingPrintStream) { - - this.mStringMask = pStringMask; - this.mDebugging = pDebugging; - this.out = pDebuggingPrintStream; - mInitialized = buildAutomaton(); - } - - // Methods - private boolean checkIfStateInWildcardRange(WildcardStringParserState pState) { - - WildcardStringParserState runnerState = pState; - - while (runnerState.mPreviousState != null) { - runnerState = runnerState.mPreviousState; - if (isFreeRangeCharacter(runnerState.mChar)) { - return true; - } - if (!isFreePassCharacter(runnerState.mChar)) { - return false; - } // If free-pass char '?' - move on - } - return false; - } - - private boolean checkIfLastFreeRangeState(WildcardStringParserState pState) { - - if (isFreeRangeCharacter(pState.mChar)) { - return true; - } - if (isFreePassCharacter(pState.mChar)) { - if (checkIfStateInWildcardRange(pState)) { - return true; - } - } - return false; - } - - /** - * @return {@code true} if and only if the string mask only consists of free-range wildcard character(s). - */ - private boolean isTrivialAutomaton() { - - for (int i = 0; i < mStringMask.length(); i++) { - if (!isFreeRangeCharacter(mStringMask.charAt(i))) { - return false; - } - } - return true; - } - - private boolean buildAutomaton() { - - char activeChar; - WildcardStringParserState runnerState = null; - WildcardStringParserState newState = null; - WildcardStringParserState lastFreeRangeState = null; - - // Create the initial state of the automaton - if ((mStringMask != null) && (mStringMask.length() > 0)) { - newState = new WildcardStringParserState(mStringMask.charAt(0)); - newState.mAutomatonStateNumber = 0; - newState.mPreviousState = null; - if (checkIfLastFreeRangeState(newState)) { - lastFreeRangeState = newState; - } - runnerState = newState; - mInitialState = runnerState; - mInitialState.mAutomatonStateNumber = 0; - } else { - System.err.println(DebugUtil.getPrefixErrorMessage(this) + "string mask provided are null or empty - aborting!"); - return false; - } - - // Create the rest of the automaton - for (int i = 1; i < mStringMask.length(); i++) { - activeChar = mStringMask.charAt(i); - - // Check if the char is an element in the alphabet or is a wildcard character - if (!((isInAlphabet(activeChar)) || (isWildcardCharacter(activeChar)))) { - System.err.println(DebugUtil.getPrefixErrorMessage(this) - + "one or more characters in string mask are not legal characters - aborting!"); - return false; - } - - // Set last free-range state before creating/checking the next state - runnerState.mLastFreeRangeState = lastFreeRangeState; - - // Create next state, check if free-range state, set the state number and preceeding state - newState = new WildcardStringParserState(activeChar); - newState.mAutomatonStateNumber = i; - newState.mPreviousState = runnerState; - - // Special check if the state represents an '*' or '?' with only preceeding states representing '?' and '*' - if (checkIfLastFreeRangeState(newState)) { - lastFreeRangeState = newState; - } - - // Set the succeding state before moving to the next state - runnerState.mNextState = newState; - - // Move to the next state - runnerState = newState; - - // Special setting of the last free-range state for the last element - if (runnerState.mAutomatonStateNumber == mStringMask.length() - 1) { - runnerState.mLastFreeRangeState = lastFreeRangeState; - } - } - - // Initiate some statistics - mTotalNumberOfStringsParsed = 0; - return true; - } - - /** - * Tests if a certain character is a valid character in the alphabet that is applying for this automaton. - */ - public static boolean isInAlphabet(final char pCharToCheck) { - - for (int i = 0; i < ALPHABET.length; i++) { - if (pCharToCheck == ALPHABET[i]) { - return true; - } - } - return false; - } - - /** - * Tests if a certain character is the designated "free-range" character ('*'). - */ - public static boolean isFreeRangeCharacter(final char pCharToCheck) { - return pCharToCheck == FREE_RANGE_CHARACTER; - } - - /** - * Tests if a certain character is the designated "free-pass" character ('?'). - */ - public static boolean isFreePassCharacter(final char pCharToCheck) { - return pCharToCheck == FREE_PASS_CHARACTER; - } - - /** - * Tests if a certain character is a wildcard character ('*' or '?'). - */ - public static boolean isWildcardCharacter(final char pCharToCheck) { - return ((isFreeRangeCharacter(pCharToCheck)) || (isFreePassCharacter(pCharToCheck))); - } - - /** - * Gets the string mask that was used when building the parser atomaton. - *

- * @return the string mask used for building the parser automaton. - */ - public String getStringMask() { - return mStringMask; - } - - /** - * Parses a string according to the rules stated above. - *

- * @param pStringToParse the string to parse. - * @return {@code true} if and only if the string are accepted by the automaton. - */ - public boolean parseString(final String pStringToParse) { - - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing \"" + pStringToParse + "\"..."); - } - - // Update statistics - mTotalNumberOfStringsParsed++; - - // Check string to be parsed for nullness - if (pStringToParse == null) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "string to be parsed is null - rejection!"); - } - return false; - } - - // Create parsable string - ParsableString parsableString = new ParsableString(pStringToParse); - - // Check string to be parsed - if (!parsableString.checkString()) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) - + "one or more characters in string to be parsed are not legal characters - rejection!"); - } - return false; - } - - // Check if automaton is correctly initialized - if (!mInitialized) { - System.err.println(DebugUtil.getPrefixErrorMessage(this) + "automaton is not initialized - rejection!"); - return false; - } - - // Check if automaton is trivial (accepts all strings) - if (isTrivialAutomaton()) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) - + "automaton represents a trivial string mask (accepts all strings) - acceptance!"); - } - return true; - } - - // Check if string to be parsed is empty - if (parsableString.isEmpty()) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "string to be parsed is empty and not trivial automaton - rejection!"); - } - return false; - } - - // Flag and more to indicate that state skipping due to sequence of '?' succeeding a '*' has been performed - boolean hasPerformedFreeRangeMovement = false; - int numberOfFreePassCharactersRead_SinceLastFreePassState = 0; - int numberOfParsedCharactersRead_SinceLastFreePassState = 0; - WildcardStringParserState runnerState = null; - - // Accepted by the first state? - if ((parsableString.mCharArray[0] == mInitialState.mChar) || isWildcardCharacter(mInitialState.mChar)) { - runnerState = mInitialState; - parsableString.mIndex = 0; - } else { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "cannot enter first automaton state - rejection!"); - } - return false; - } - - // Initialize the free-pass character state visited count - if (isFreePassCharacter(runnerState.mChar)) { - numberOfFreePassCharactersRead_SinceLastFreePassState++; - } - - // Perform parsing according to the rules above - for (int i = 0; i < parsableString.length(); i++) { - if (mDebugging) { - out.println(); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - index number " + i + ", active char: '" - + parsableString.getActiveChar() + "' char string index: " + parsableString.mIndex - + " number of chars since last free-range state: " + numberOfParsedCharactersRead_SinceLastFreePassState); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - state: " + runnerState.mAutomatonStateNumber + " '" - + runnerState.mChar + "' - no of free-pass chars read: " + numberOfFreePassCharactersRead_SinceLastFreePassState); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - hasPerformedFreeRangeMovement: " + hasPerformedFreeRangeMovement); - } - if (runnerState.mNextState == null) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - runnerState.mNextState == null"); - } - - // If there are no subsequent state (final state) and the state represents '*' - acceptance! - if (isFreeRangeCharacter(runnerState.mChar)) { - - // Special free-range skipping check - if (hasPerformedFreeRangeMovement) { - if (parsableString.reachedEndOfString()) { - if (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState) { - if (mDebugging) { - out.println( - DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and the state represents '*' - end of parsing string, but not enough characters read - rejection!"); - } - return false; - } else { - if (mDebugging) { - out.println( - DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and the state represents '*' - end of parsing string and enough characters read - acceptance!"); - } - return true; - } - } else { - if (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState) { - if (mDebugging) { - out.println( - DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and the state represents '*' - not the end of parsing string and not enough characters read - read next character"); - } - parsableString.mIndex++; - numberOfParsedCharactersRead_SinceLastFreePassState++; - } else { - if (mDebugging) { - out.println( - DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and the state represents '*' - not the end of parsing string, but enough characters read - acceptance!"); - } - return true; - } - } - } else { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and the state represents '*' - no skipping performed - acceptance!"); - } - return true; - } - } - - // If there are no subsequent state (final state) and no skipping has been performed and the end of the string to test is reached - acceptance! - else if (parsableString.reachedEndOfString()) { - - // Special free-range skipping check - if ((hasPerformedFreeRangeMovement) - && (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState)) { - if (mDebugging) { - out.println( - DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and skipping has been performed and end of parsing string, but not enough characters read - rejection!"); - } - return false; - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) - + "no subsequent state (final state) and the end of the string to test is reached - acceptance!"); - } - return true; - } else { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - escaping process..."); - } - } - } else { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - runnerState.mNextState != null"); - } - - // Special Case: - // If this state represents '*' - go to the rightmost state representing '?'. - // This state will act as an '*' - except that you only can go to the next state or accept the string, if and only if the number of '?' read are equal or less than the number of character read from the parsing string. - if (isFreeRangeCharacter(runnerState.mChar)) { - numberOfFreePassCharactersRead_SinceLastFreePassState = 0; - numberOfParsedCharactersRead_SinceLastFreePassState = 0; - WildcardStringParserState freeRangeRunnerState = runnerState.mNextState; - - while ((freeRangeRunnerState != null) && (isFreePassCharacter(freeRangeRunnerState.mChar))) { - runnerState = freeRangeRunnerState; - hasPerformedFreeRangeMovement = true; - numberOfFreePassCharactersRead_SinceLastFreePassState++; - freeRangeRunnerState = freeRangeRunnerState.mNextState; - } - - // Special Case: if the mask is at the end - if (runnerState.mNextState == null) { - if (mDebugging) { - out.println(); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - index number " + i + ", active char: '" - + parsableString.getActiveChar() + "' char string index: " + parsableString.mIndex - + " number of chars since last free-range state: " + numberOfParsedCharactersRead_SinceLastFreePassState); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - state: " + runnerState.mAutomatonStateNumber + " '" - + runnerState.mChar + "' - no of free-pass chars read: " + numberOfFreePassCharactersRead_SinceLastFreePassState); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing - hasPerformedFreeRangeMovement: " - + hasPerformedFreeRangeMovement); - } - if ((hasPerformedFreeRangeMovement) - && (numberOfFreePassCharactersRead_SinceLastFreePassState >= numberOfParsedCharactersRead_SinceLastFreePassState)) { - return true; - } else { - return false; - } - } - } - - // If the next state represents '*' - go to this next state - if (isFreeRangeCharacter(runnerState.mNextState.mChar)) { - runnerState = runnerState.mNextState; - parsableString.mIndex++; - numberOfParsedCharactersRead_SinceLastFreePassState++; - } - - // If the next state represents '?' - go to this next state - else if (isFreePassCharacter(runnerState.mNextState.mChar)) { - runnerState = runnerState.mNextState; - parsableString.mIndex++; - numberOfFreePassCharactersRead_SinceLastFreePassState++; - numberOfParsedCharactersRead_SinceLastFreePassState++; - } - - // If the next state represents the same character as the next character in the string to test - go to this next state - else if ((!parsableString.reachedEndOfString()) && (runnerState.mNextState.mChar == parsableString.getSubsequentChar())) { - runnerState = runnerState.mNextState; - parsableString.mIndex++; - numberOfParsedCharactersRead_SinceLastFreePassState++; - } - - // If the next character in the string to test does not coincide with the next state - go to the last state representing '*'. If there are none - rejection! - else if (runnerState.mLastFreeRangeState != null) { - runnerState = runnerState.mLastFreeRangeState; - parsableString.mIndex++; - numberOfParsedCharactersRead_SinceLastFreePassState++; - } else { - if (mDebugging) { - out.println( - DebugUtil.getPrefixDebugMessage(this) - + "the next state does not represent the same character as the next character in the string to test, and there are no last-free-range-state - rejection!"); - } - return false; - } - } - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "finished reading parsing string and not at any final state - rejection!"); - } - return false; - } - - /* - * Overriding mandatory methods from EntityObject's. - */ - - /** - * Method toString - * - * - * @return - * - */ - public String toString() { - - StringBuilder buffer = new StringBuilder(); - - if (!mInitialized) { - buffer.append(DebugUtil.getClassName(this)); - buffer.append(": Not initialized properly!"); - buffer.append("\n"); - buffer.append("\n"); - } else { - WildcardStringParserState runnerState = mInitialState; - - buffer.append(DebugUtil.getClassName(this)); - buffer.append(": String mask "); - buffer.append(mStringMask); - buffer.append("\n"); - buffer.append("\n"); - buffer.append(" Automaton: "); - while (runnerState != null) { - buffer.append(runnerState.mAutomatonStateNumber); - buffer.append(": "); - buffer.append(runnerState.mChar); - buffer.append(" ("); - if (runnerState.mLastFreeRangeState != null) { - buffer.append(runnerState.mLastFreeRangeState.mAutomatonStateNumber); - } else { - buffer.append("-"); - } - buffer.append(")"); - if (runnerState.mNextState != null) { - buffer.append(" --> "); - } - runnerState = runnerState.mNextState; - } - buffer.append("\n"); - buffer.append(" Format: : ()"); - buffer.append("\n"); - buffer.append(" Number of strings parsed: " + mTotalNumberOfStringsParsed); - buffer.append("\n"); - } - return buffer.toString(); - } - - /** - * Method equals - * - * - * @param pObject - * - * @return - * - */ - public boolean equals(Object pObject) { - - if (pObject instanceof WildcardStringParser) { - WildcardStringParser externalParser = (WildcardStringParser) pObject; - - return ((externalParser.mInitialized == this.mInitialized) && (externalParser.mStringMask == this.mStringMask)); - } - return super.equals(pObject); - } - - // Just taking the lazy, easy and dangerous way out - - /** - * Method hashCode - * - * - * @return - * - */ - public int hashCode() { - return super.hashCode(); - } - - protected Object clone() throws CloneNotSupportedException { - - if (mInitialized) { - return new WildcardStringParser(mStringMask); - } - return null; - } - - // Just taking the lazy, easy and dangerous way out - protected void finalize() throws Throwable {} - - /** - * A simple holder class for an automaton state. - */ - class WildcardStringParserState { - // Constants - // Members - int mAutomatonStateNumber; - char mChar; - WildcardStringParserState mPreviousState; - WildcardStringParserState mNextState; - WildcardStringParserState mLastFreeRangeState; + /** Field ALPHABET */ + public static final char[] ALPHABET = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'æ', + 'ø', 'å', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'N', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', 'Æ', 'Ø', 'Å', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' + }; + + /** Field FREE_RANGE_CHARACTER */ + public static final char FREE_RANGE_CHARACTER = '*'; + + /** Field FREE_PASS_CHARACTER */ + public static final char FREE_PASS_CHARACTER = '?'; + + // Members + boolean mInitialized; + String mStringMask; + WildcardStringParserState mInitialState; + int mTotalNumberOfStringsParsed; + boolean mDebugging; + PrintStream out; + + // Properties // Constructors /** - * Constructor WildcardStringParserState - * - * - * @param pChar + * Creates a wildcard string parser. + *

* + * @param pStringMask the wildcard string mask. */ - public WildcardStringParserState(final char pChar) { - this.mChar = pChar; + public WildcardStringParser(final String pStringMask) { + this(pStringMask, false); + } + + /** + * Creates a wildcard string parser. + *

+ * + * @param pStringMask the wildcard string mask. + * @param pDebugging {@code true} will cause debug messages to be emitted to {@code System.out}. + */ + public WildcardStringParser(final String pStringMask, final boolean pDebugging) { + this(pStringMask, pDebugging, System.out); + } + + /** + * Creates a wildcard string parser. + *

+ * + * @param pStringMask the wildcard string mask. + * @param pDebugging {@code true} will cause debug messages to be emitted. + * @param pDebuggingPrintStream the {@code java.io.PrintStream} to which the debug messages will be emitted. + */ + public WildcardStringParser(final String pStringMask, final boolean pDebugging, final PrintStream pDebuggingPrintStream) { + + this.mStringMask = pStringMask; + this.mDebugging = pDebugging; + this.out = pDebuggingPrintStream; + mInitialized = buildAutomaton(); } // Methods - // Debug - } + private boolean checkIfStateInWildcardRange(WildcardStringParserState pState) { - /** - * A simple holder class for a string to be parsed. - */ - class ParsableString { + WildcardStringParserState runnerState = pState; - // Constants - // Members - char[] mCharArray; - int mIndex; - - // Constructors - ParsableString(final String pStringToParse) { - - if (pStringToParse != null) { - mCharArray = pStringToParse.toCharArray(); - } - mIndex = -1; - } - - // Methods - boolean reachedEndOfString() { - - //System.out.println(DebugUtil.DEBUG + DebugUtil.getClassName(this) + ": mIndex :" + mIndex); - //System.out.println(DebugUtil.DEBUG + DebugUtil.getClassName(this) + ": mCharArray.length :" + mCharArray.length); - return mIndex == mCharArray.length - 1; - } - - int length() { - return mCharArray.length; - } - - char getActiveChar() { - - if ((mIndex > -1) && (mIndex < mCharArray.length)) { - return mCharArray[mIndex]; - } - System.err.println(DebugUtil.ERROR + DebugUtil.getClassName(this) + ": trying to access character outside character array!"); - return ' '; - } - - char getSubsequentChar() { - - if ((mIndex > -1) && (mIndex + 1 < mCharArray.length)) { - return mCharArray[mIndex + 1]; - } - System.err.println(DebugUtil.ERROR + DebugUtil.getClassName(this) + ": trying to access character outside character array!"); - return ' '; - } - - boolean checkString() { - - if (!isEmpty()) { - - // Check if the string only contains chars that are elements in the alphabet - for (int i = 0; i < mCharArray.length; i++) { - if (!WildcardStringParser.isInAlphabet(mCharArray[i])) { - return false; - } + while (runnerState.mPreviousState != null) { + runnerState = runnerState.mPreviousState; + if (isFreeRangeCharacter(runnerState.mChar)) { + return true; + } + if (!isFreePassCharacter(runnerState.mChar)) { + return false; + } // If free-pass char '?' - move on } - } - return true; + return false; } - boolean isEmpty() { - return ((mCharArray == null) || (mCharArray.length == 0)); + private boolean checkIfLastFreeRangeState(WildcardStringParserState pState) { + + if (isFreeRangeCharacter(pState.mChar)) { + return true; + } + if (isFreePassCharacter(pState.mChar)) { + if (checkIfStateInWildcardRange(pState)) { + return true; + } + } + return false; } + /** @return {@code true} if and only if the string mask only consists of free-range wildcard character(s). */ + private boolean isTrivialAutomaton() { + + for (int i = 0; i < mStringMask.length(); i++) { + if (!isFreeRangeCharacter(mStringMask.charAt(i))) { + return false; + } + } + return true; + } + + private boolean buildAutomaton() { + + char activeChar; + WildcardStringParserState runnerState = null; + WildcardStringParserState newState = null; + WildcardStringParserState lastFreeRangeState = null; + + // Create the initial state of the automaton + if ((mStringMask != null) && (mStringMask.length() > 0)) { + newState = new WildcardStringParserState(mStringMask.charAt(0)); + newState.mAutomatonStateNumber = 0; + newState.mPreviousState = null; + if (checkIfLastFreeRangeState(newState)) { + lastFreeRangeState = newState; + } + runnerState = newState; + mInitialState = runnerState; + mInitialState.mAutomatonStateNumber = 0; + } + else { + System.err.println("string mask provided are null or empty - aborting!"); + return false; + } + + // Create the rest of the automaton + for (int i = 1; i < mStringMask.length(); i++) { + activeChar = mStringMask.charAt(i); + + // Check if the char is an element in the alphabet or is a wildcard character + if (!((isInAlphabet(activeChar)) || (isWildcardCharacter(activeChar)))) { + System.err.println("one or more characters in string mask are not legal characters - aborting!"); + return false; + } + + // Set last free-range state before creating/checking the next state + runnerState.mLastFreeRangeState = lastFreeRangeState; + + // Create next state, check if free-range state, set the state number and preceeding state + newState = new WildcardStringParserState(activeChar); + newState.mAutomatonStateNumber = i; + newState.mPreviousState = runnerState; + + // Special check if the state represents an '*' or '?' with only preceeding states representing '?' and '*' + if (checkIfLastFreeRangeState(newState)) { + lastFreeRangeState = newState; + } + + // Set the succeding state before moving to the next state + runnerState.mNextState = newState; + + // Move to the next state + runnerState = newState; + + // Special setting of the last free-range state for the last element + if (runnerState.mAutomatonStateNumber == mStringMask.length() - 1) { + runnerState.mLastFreeRangeState = lastFreeRangeState; + } + } + + // Initiate some statistics + mTotalNumberOfStringsParsed = 0; + return true; + } + + /** Tests if a certain character is a valid character in the alphabet that is applying for this automaton. */ + public static boolean isInAlphabet(final char pCharToCheck) { + + for (int i = 0; i < ALPHABET.length; i++) { + if (pCharToCheck == ALPHABET[i]) { + return true; + } + } + return false; + } + + /** Tests if a certain character is the designated "free-range" character ('*'). */ + public static boolean isFreeRangeCharacter(final char pCharToCheck) { + return pCharToCheck == FREE_RANGE_CHARACTER; + } + + /** Tests if a certain character is the designated "free-pass" character ('?'). */ + public static boolean isFreePassCharacter(final char pCharToCheck) { + return pCharToCheck == FREE_PASS_CHARACTER; + } + + /** Tests if a certain character is a wildcard character ('*' or '?'). */ + public static boolean isWildcardCharacter(final char pCharToCheck) { + return ((isFreeRangeCharacter(pCharToCheck)) || (isFreePassCharacter(pCharToCheck))); + } + + /** + * Gets the string mask that was used when building the parser atomaton. + *

+ * + * @return the string mask used for building the parser automaton. + */ + public String getStringMask() { + return mStringMask; + } + + /** + * Parses a string according to the rules stated above. + *

+ * + * @param pStringToParse the string to parse. + * @return {@code true} if and only if the string are accepted by the automaton. + */ + public boolean parseString(final String pStringToParse) { + + if (mDebugging) { + out.println("parsing \"" + pStringToParse + "\"..."); + } + + // Update statistics + mTotalNumberOfStringsParsed++; + + // Check string to be parsed for nullness + if (pStringToParse == null) { + if (mDebugging) { + out.println("string to be parsed is null - rejection!"); + } + return false; + } + + // Create parsable string + ParsableString parsableString = new ParsableString(pStringToParse); + + // Check string to be parsed + if (!parsableString.checkString()) { + if (mDebugging) { + out.println("one or more characters in string to be parsed are not legal characters - rejection!"); + } + return false; + } + + // Check if automaton is correctly initialized + if (!mInitialized) { + System.err.println("automaton is not initialized - rejection!"); + return false; + } + + // Check if automaton is trivial (accepts all strings) + if (isTrivialAutomaton()) { + if (mDebugging) { + out.println("automaton represents a trivial string mask (accepts all strings) - acceptance!"); + } + return true; + } + + // Check if string to be parsed is empty + if (parsableString.isEmpty()) { + if (mDebugging) { + out.println("string to be parsed is empty and not trivial automaton - rejection!"); + } + return false; + } + + // Flag and more to indicate that state skipping due to sequence of '?' succeeding a '*' has been performed + boolean hasPerformedFreeRangeMovement = false; + int numberOfFreePassCharactersRead_SinceLastFreePassState = 0; + int numberOfParsedCharactersRead_SinceLastFreePassState = 0; + WildcardStringParserState runnerState = null; + + // Accepted by the first state? + if ((parsableString.mCharArray[0] == mInitialState.mChar) || isWildcardCharacter(mInitialState.mChar)) { + runnerState = mInitialState; + parsableString.mIndex = 0; + } + else { + if (mDebugging) { + out.println("cannot enter first automaton state - rejection!"); + } + return false; + } + + // Initialize the free-pass character state visited count + if (isFreePassCharacter(runnerState.mChar)) { + numberOfFreePassCharactersRead_SinceLastFreePassState++; + } + + // Perform parsing according to the rules above + for (int i = 0; i < parsableString.length(); i++) { + if (mDebugging) { + out.println(); + } + if (mDebugging) { + out.println("parsing - index number " + i + ", active char: '" + + parsableString.getActiveChar() + "' char string index: " + parsableString.mIndex + + " number of chars since last free-range state: " + numberOfParsedCharactersRead_SinceLastFreePassState); + } + if (mDebugging) { + out.println("parsing - state: " + runnerState.mAutomatonStateNumber + " '" + + runnerState.mChar + "' - no of free-pass chars read: " + numberOfFreePassCharactersRead_SinceLastFreePassState); + } + if (mDebugging) { + out.println("parsing - hasPerformedFreeRangeMovement: " + hasPerformedFreeRangeMovement); + } + if (runnerState.mNextState == null) { + if (mDebugging) { + out.println("parsing - runnerState.mNextState == null"); + } + + // If there are no subsequent state (final state) and the state represents '*' - acceptance! + if (isFreeRangeCharacter(runnerState.mChar)) { + + // Special free-range skipping check + if (hasPerformedFreeRangeMovement) { + if (parsableString.reachedEndOfString()) { + if (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState) { + if (mDebugging) { + out.println( + "no subsequent state (final state) and the state represents '*' - end of parsing string, but not enough characters read - rejection!"); + } + return false; + } + else { + if (mDebugging) { + out.println( + "no subsequent state (final state) and the state represents '*' - end of parsing string and enough characters read - acceptance!"); + } + return true; + } + } + else { + if (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState) { + if (mDebugging) { + out.println( + "no subsequent state (final state) and the state represents '*' - not the end of parsing string and not enough characters read - read next character"); + } + parsableString.mIndex++; + numberOfParsedCharactersRead_SinceLastFreePassState++; + } + else { + if (mDebugging) { + out.println( + "no subsequent state (final state) and the state represents '*' - not the end of parsing string, but enough characters read - acceptance!"); + } + return true; + } + } + } + else { + if (mDebugging) { + out.println("no subsequent state (final state) and the state represents '*' - no skipping performed - acceptance!"); + } + return true; + } + } + + // If there are no subsequent state (final state) and no skipping has been performed and the end of the string to test is reached - acceptance! + else if (parsableString.reachedEndOfString()) { + + // Special free-range skipping check + if ((hasPerformedFreeRangeMovement) + && (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState)) { + if (mDebugging) { + out.println( + "no subsequent state (final state) and skipping has been performed and end of parsing string, but not enough characters read - rejection!"); + } + return false; + } + if (mDebugging) { + out.println("no subsequent state (final state) and the end of the string to test is reached - acceptance!"); + } + return true; + } + else { + if (mDebugging) { + out.println("parsing - escaping process..."); + } + } + } + else { + if (mDebugging) { + out.println("parsing - runnerState.mNextState != null"); + } + + // Special Case: + // If this state represents '*' - go to the rightmost state representing '?'. + // This state will act as an '*' - except that you only can go to the next state or accept the string, if and only if the number of '?' read are equal or less than the number of character read from the parsing string. + if (isFreeRangeCharacter(runnerState.mChar)) { + numberOfFreePassCharactersRead_SinceLastFreePassState = 0; + numberOfParsedCharactersRead_SinceLastFreePassState = 0; + WildcardStringParserState freeRangeRunnerState = runnerState.mNextState; + + while ((freeRangeRunnerState != null) && (isFreePassCharacter(freeRangeRunnerState.mChar))) { + runnerState = freeRangeRunnerState; + hasPerformedFreeRangeMovement = true; + numberOfFreePassCharactersRead_SinceLastFreePassState++; + freeRangeRunnerState = freeRangeRunnerState.mNextState; + } + + // Special Case: if the mask is at the end + if (runnerState.mNextState == null) { + if (mDebugging) { + out.println(); + } + if (mDebugging) { + out.println("parsing - index number " + i + ", active char: '" + + parsableString.getActiveChar() + "' char string index: " + parsableString.mIndex + + " number of chars since last free-range state: " + numberOfParsedCharactersRead_SinceLastFreePassState); + } + if (mDebugging) { + out.println("parsing - state: " + runnerState.mAutomatonStateNumber + " '" + + runnerState.mChar + "' - no of free-pass chars read: " + numberOfFreePassCharactersRead_SinceLastFreePassState); + } + if (mDebugging) { + out.println("parsing - hasPerformedFreeRangeMovement: " + + hasPerformedFreeRangeMovement); + } + if ((hasPerformedFreeRangeMovement) + && (numberOfFreePassCharactersRead_SinceLastFreePassState >= numberOfParsedCharactersRead_SinceLastFreePassState)) { + return true; + } + else { + return false; + } + } + } + + // If the next state represents '*' - go to this next state + if (isFreeRangeCharacter(runnerState.mNextState.mChar)) { + runnerState = runnerState.mNextState; + parsableString.mIndex++; + numberOfParsedCharactersRead_SinceLastFreePassState++; + } + + // If the next state represents '?' - go to this next state + else if (isFreePassCharacter(runnerState.mNextState.mChar)) { + runnerState = runnerState.mNextState; + parsableString.mIndex++; + numberOfFreePassCharactersRead_SinceLastFreePassState++; + numberOfParsedCharactersRead_SinceLastFreePassState++; + } + + // If the next state represents the same character as the next character in the string to test - go to this next state + else if ((!parsableString.reachedEndOfString()) && (runnerState.mNextState.mChar == parsableString.getSubsequentChar())) { + runnerState = runnerState.mNextState; + parsableString.mIndex++; + numberOfParsedCharactersRead_SinceLastFreePassState++; + } + + // If the next character in the string to test does not coincide with the next state - go to the last state representing '*'. If there are none - rejection! + else if (runnerState.mLastFreeRangeState != null) { + runnerState = runnerState.mLastFreeRangeState; + parsableString.mIndex++; + numberOfParsedCharactersRead_SinceLastFreePassState++; + } + else { + if (mDebugging) { + out.println("the next state does not represent the same character as the next character in the string to test, and there are no last-free-range-state - rejection!"); + } + return false; + } + } + } + if (mDebugging) { + out.println("finished reading parsing string and not at any final state - rejection!"); + } + return false; + } + + /* + * Overriding mandatory methods from EntityObject's. + */ + /** * Method toString * - * * @return - * */ public String toString() { - return new String(mCharArray); + + StringBuilder buffer = new StringBuilder(); + + if (!mInitialized) { + buffer.append(getClass().getName()); + buffer.append(": Not initialized properly!"); + buffer.append("\n"); + buffer.append("\n"); + } + else { + WildcardStringParserState runnerState = mInitialState; + + buffer.append(getClass().getName()); + buffer.append(": String mask "); + buffer.append(mStringMask); + buffer.append("\n"); + buffer.append("\n"); + buffer.append(" Automaton: "); + while (runnerState != null) { + buffer.append(runnerState.mAutomatonStateNumber); + buffer.append(": "); + buffer.append(runnerState.mChar); + buffer.append(" ("); + if (runnerState.mLastFreeRangeState != null) { + buffer.append(runnerState.mLastFreeRangeState.mAutomatonStateNumber); + } + else { + buffer.append("-"); + } + buffer.append(")"); + if (runnerState.mNextState != null) { + buffer.append(" --> "); + } + runnerState = runnerState.mNextState; + } + buffer.append("\n"); + buffer.append(" Format: : ()"); + buffer.append("\n"); + buffer.append(" Number of strings parsed: " + mTotalNumberOfStringsParsed); + buffer.append("\n"); + } + return buffer.toString(); + } + + /** + * Method equals + * + * @param pObject + * @return + */ + public boolean equals(Object pObject) { + + if (pObject instanceof WildcardStringParser) { + WildcardStringParser externalParser = (WildcardStringParser) pObject; + + return ((externalParser.mInitialized == this.mInitialized) && (externalParser.mStringMask == this.mStringMask)); + } + return super.equals(pObject); + } + + // Just taking the lazy, easy and dangerous way out + + /** + * Method hashCode + * + * @return + */ + public int hashCode() { + return super.hashCode(); + } + + protected Object clone() throws CloneNotSupportedException { + + if (mInitialized) { + return new WildcardStringParser(mStringMask); + } + return null; + } + + // Just taking the lazy, easy and dangerous way out + protected void finalize() throws Throwable { + } + + /** A simple holder class for an automaton state. */ + class WildcardStringParserState { + + // Constants + // Members + int mAutomatonStateNumber; + char mChar; + WildcardStringParserState mPreviousState; + WildcardStringParserState mNextState; + WildcardStringParserState mLastFreeRangeState; + + // Constructors + + /** + * Constructor WildcardStringParserState + * + * @param pChar + */ + public WildcardStringParserState(final char pChar) { + this.mChar = pChar; + } + + // Methods + // Debug + } + + /** A simple holder class for a string to be parsed. */ + class ParsableString { + + // Constants + // Members + char[] mCharArray; + int mIndex; + + // Constructors + ParsableString(final String pStringToParse) { + + if (pStringToParse != null) { + mCharArray = pStringToParse.toCharArray(); + } + mIndex = -1; + } + + // Methods + boolean reachedEndOfString() { + + //System.out.println(DebugUtil.DEBUG + DebugUtil.getClassName(this) + ": mIndex :" + mIndex); + //System.out.println(DebugUtil.DEBUG + DebugUtil.getClassName(this) + ": mCharArray.length :" + mCharArray.length); + return mIndex == mCharArray.length - 1; + } + + int length() { + return mCharArray.length; + } + + char getActiveChar() { + + if ((mIndex > -1) && (mIndex < mCharArray.length)) { + return mCharArray[mIndex]; + } + System.err.println(getClass().getName() + ": trying to access character outside character array!"); + return ' '; + } + + char getSubsequentChar() { + + if ((mIndex > -1) && (mIndex + 1 < mCharArray.length)) { + return mCharArray[mIndex + 1]; + } + System.err.println(getClass().getName() + ": trying to access character outside character array!"); + return ' '; + } + + boolean checkString() { + + if (!isEmpty()) { + + // Check if the string only contains chars that are elements in the alphabet + for (int i = 0; i < mCharArray.length; i++) { + if (!WildcardStringParser.isInAlphabet(mCharArray[i])) { + return false; + } + } + } + return true; + } + + boolean isEmpty() { + return ((mCharArray == null) || (mCharArray.length == 0)); + } + + /** + * Method toString + * + * @return + */ + public String toString() { + return new String(mCharArray); + } } - } } diff --git a/twelvemonkeys-imageio/jmagick/pom.xml b/twelvemonkeys-imageio/jmagick/pom.xml index 03927569..ac203146 100644 --- a/twelvemonkeys-imageio/jmagick/pom.xml +++ b/twelvemonkeys-imageio/jmagick/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.twelvemonkeys.imageio twelvemonkeys-imageio-jmagick - 2.2-SNAPSHOT + 2.2 TwelveMonkeys ImageIO JMagick Plugin twelvemonkeys-imageio com.twelvemonkeys - 2.2-SNAPSHOT + 2.2 diff --git a/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/QDTest.java b/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/QDTest.java old mode 100755 new mode 100644 index a58cbeeb..425be0d3 --- a/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/QDTest.java +++ b/twelvemonkeys-imageio/pict/src/main/java/com/twelvemonkeys/imageio/plugins/pict/QDTest.java @@ -28,10 +28,13 @@ package com.twelvemonkeys.imageio.plugins.pict; -import com.twelvemonkeys.image.ConvolveTester; +import com.twelvemonkeys.image.BufferedImageIcon; +import com.twelvemonkeys.image.ImageUtil; +import javax.swing.*; import java.awt.image.BufferedImage; import java.awt.*; +import java.lang.reflect.InvocationTargetException; /** * QDTest @@ -125,6 +128,34 @@ public class QDTest { context.closePicture(); } - ConvolveTester.showIt(image, "QuickDraw Test"); + showIt(image, "QuickDraw Test"); } + + public static void showIt(final BufferedImage pImage, final String pTitle) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JFrame frame = new JFrame(pTitle); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLocationByPlatform(true); + JPanel pane = new JPanel(new BorderLayout()); + GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); + BufferedImageIcon icon = new BufferedImageIcon(ImageUtil.accelerate(pImage, gc)); + JScrollPane scroll = new JScrollPane(new JLabel(icon)); + scroll.setBorder(null); + pane.add(scroll); + frame.setContentPane(pane); + frame.pack(); + frame.setVisible(true); + } + }); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/ConvolveTester.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/ConvolveTester.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/ConvolveTester.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/ConvolveTester.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/EasyImage.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/EasyImage.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/EasyImage.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/EasyImage.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/SubsampleTester.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/SubsampleTester.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/SubsampleTester.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/image/SubsampleTester.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/NativeLoader.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/lang/NativeLoader.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/NativeLoader.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/lang/NativeLoader.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/DebugUtil.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/util/DebugUtil.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/DebugUtil.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/util/DebugUtil.java diff --git a/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java b/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java similarity index 100% rename from twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java rename to twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java diff --git a/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletUtil.java b/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletUtil.java index 89724afe..df937202 100755 --- a/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletUtil.java +++ b/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/ServletUtil.java @@ -29,7 +29,6 @@ package com.twelvemonkeys.servlet; import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.util.DebugUtil; import com.twelvemonkeys.util.convert.ConversionException; import com.twelvemonkeys.util.convert.Converter; @@ -45,6 +44,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URL; +import java.util.Date; import java.util.Enumeration; import java.util.List; import java.util.Map; @@ -154,7 +154,7 @@ public final class ServletUtil { // public static T getParameter(ServletRequest pReq, String pName, // String pFormat, T pDefault) { - static Object getParameter(ServletRequest pReq, String pName, Class pType, String pFormat, Object pDefault) { + static T getParameter(ServletRequest pReq, String pName, Class pType, String pFormat, T pDefault) { // Test if pDefault is either null or instance of pType if (pDefault != null && !pType.isInstance(pDefault)) { throw new IllegalArgumentException("default value not instance of " + pType + ": " + pDefault.getClass()); @@ -166,7 +166,7 @@ public final class ServletUtil { return pDefault; } try { - return Converter.getInstance().toObject(str, pType, pFormat); + return pType.cast(Converter.getInstance().toObject(str, pType, pFormat)); } catch (ConversionException ce) { return pDefault; @@ -949,14 +949,14 @@ public final class ServletUtil { // recieved the request buffer.append(indentation); buffer.append("Last accessed time: "); - buffer.append(DebugUtil.getTimestamp(pHttpSession.getLastAccessedTime())); + buffer.append(new Date(pHttpSession.getLastAccessedTime())); buffer.append("\n"); // Returns the time when this session was created, measured in // milliseconds since midnight January 1, 1970 GMT buffer.append(indentation); buffer.append("Creation time: "); - buffer.append(DebugUtil.getTimestamp(pHttpSession.getCreationTime())); + buffer.append(new Date(pHttpSession.getCreationTime())); buffer.append("\n"); // Returns true if the client does not yet know about the session