001: /**********************************************************************
002: Copyright (c) 2004 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015: Contributors:
016: ...
017: **********************************************************************/package org.jpox.store.expression;
018:
019: import java.text.CharacterIterator;
020: import java.text.StringCharacterIterator;
021:
022: /**
023: * Parser for a Match Expression.
024: *
025: * @version $Revision: 1.8 $
026: **/
027: class MatchExpressionParser {
028: private final String input;
029: private final CharacterIterator ci;
030: private final char zeroOrMoreChar;
031: private final char anyChar;
032: private final char escapeChar;
033:
034: /**
035: * Constructor
036: * @param input
037: * The input string
038: * @param zeroOrMoreChar
039: * The pattern string for representing zero or more characters.
040: * Most of databases will use the percent sign character.
041: * @param anyChar
042: * The pattern string for representing one character.
043: * Most of databases will use the underscore character.
044: * @param escapeChar
045: * The pattern string for representing to escape zeroOrMoreChar or anyChar.
046: * Most of databases will use the backslash \ character.
047: **/
048: public MatchExpressionParser(String input, char zeroOrMoreChar,
049: char anyChar, char escapeChar) {
050: this .input = input;
051: this .zeroOrMoreChar = zeroOrMoreChar;
052: this .anyChar = anyChar;
053: this .escapeChar = escapeChar;
054: ci = new StringCharacterIterator(input);
055: }
056:
057: private boolean parseNextChar(char c) {
058: int savedIdx = ci.getIndex();
059: if (ci.next() == c) {
060: return true;
061: } else {
062: ci.setIndex(savedIdx);
063: return false;
064: }
065: }
066:
067: /**
068: * Parse a pattern expression
069: * @return the parsed expression
070: */
071: public String parsePattern() {
072: StringBuffer lit = new StringBuffer();
073: char c;
074:
075: while ((c = ci.current()) != CharacterIterator.DONE) {
076:
077: if (c == '\\') //escape for java match expression
078: {
079: lit.append(parseEscapedCharacter());
080: } else if (c == '.') {
081: if (parseNextChar('*')) {
082: lit.append(zeroOrMoreChar);
083: } else {
084: lit.append(anyChar);
085: }
086: } else if (c == anyChar) {
087: lit.append("" + escapeChar + anyChar);
088: } else if (c == zeroOrMoreChar) {
089: lit.append("" + escapeChar + zeroOrMoreChar);
090: } else {
091: lit.append(c);
092: }
093: ci.next();
094: }
095:
096: return lit.toString();
097: }
098:
099: private String parseEscapedCharacter() {
100: char c;
101:
102: c = ci.next();
103: if (c == CharacterIterator.DONE) {
104: return escapeChar + "\\";
105: } else if (c == '.') {
106: return ".";
107: } else if (c == '\\') {
108: // Creating a new String with \\ will swallow the escape \, so we add it back on
109: // Added as a specific case as a reminder that we need to retain the escaping
110: return escapeChar + "\\" + escapeChar + c;
111: }
112: return escapeChar + "\\" + c;
113: }
114:
115: public String toString() {
116: return input;
117: }
118: }
|