001: /*
002: (c) Copyright 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP, all rights reserved.
003: [See end of file]
004: $Id: Rewrite.java,v 1.14 2008/01/02 12:07:58 andy_seaborne Exp $
005: */
006: package com.hp.hpl.jena.graph.query;
007:
008: import com.hp.hpl.jena.graph.Node_Literal;
009:
010: /**
011: Rewrite - class which does expression rewrites for Query
012: @author kers
013: */
014: public class Rewrite {
015: public static Expression rewriteStringMatch(Expression e) {
016: Expression L = e.getArg(0), R = e.getArg(1);
017: PatternLiteral pattern = Rewrite.getPattern(R);
018: if (pattern == null)
019: return e;
020: else if (isStartsWith(pattern))
021: return startsWith(L, pattern.getPatternString()
022: .substring(1), pattern.getPatternModifiers());
023: else if (isContains(pattern))
024: return contains(L, pattern.getPatternString(), pattern
025: .getPatternModifiers());
026: else if (isEndsWith(pattern))
027: return endsWith(L, front(pattern.getPatternString()),
028: pattern.getPatternModifiers());
029: return e;
030: }
031:
032: protected static String front(String s) {
033: return s.substring(0, s.length() - 1);
034: }
035:
036: public static PatternLiteral getPattern(Expression E) {
037: if (E instanceof PatternLiteral) {
038: PatternLiteral L = (PatternLiteral) E;
039: if (L.getPatternLanguage().equals(PatternLiteral.rdql))
040: return L;
041: }
042: return null;
043: }
044:
045: /*
046: This following code for the evaluators is horrid - there's too much uncaptured
047: variation. Perhaps it will all go away when I understand how to use the
048: regex package (note, not the Java 1.4 package, because we still support
049: Java 1.3; the ORO package that RDQL uses).
050:
051: TODO clean this up.
052:
053: @author hedgehog
054: */
055: public static abstract class DyadicLiteral extends Dyadic {
056: public DyadicLiteral(Expression L, String F, String R) {
057: super (L, F, new Expression.Fixed(R));
058: }
059:
060: public boolean evalBool(Object l, Object r) {
061: return evalBool(nodeAsString(l), r.toString());
062: }
063:
064: protected String nodeAsString(Object x) {
065: return x instanceof Node_Literal ? ((Node_Literal) x)
066: .getLiteralLexicalForm() : x.toString();
067: }
068:
069: protected abstract boolean evalBool(String l, String r);
070: }
071:
072: public static Expression endsWith(Expression L,
073: final String content, String modifiers) {
074: if (modifiers.equals("i")) {
075: return new DyadicLiteral(L,
076: ExpressionFunctionURIs.J_endsWithInsensitive,
077: content) {
078: protected final String lowerContent = content
079: .toLowerCase();
080:
081: public boolean evalBool(String l, String r) {
082: return l.toLowerCase().endsWith(lowerContent);
083: }
084: };
085: } else {
086: return new DyadicLiteral(L,
087: ExpressionFunctionURIs.J_EndsWith, content) {
088: public boolean evalBool(String l, String r) {
089: return l.endsWith(r);
090: }
091: };
092: }
093: }
094:
095: public static Expression startsWith(Expression L,
096: final String content, String modifiers) {
097: if (modifiers.equals("i")) {
098: return new DyadicLiteral(L,
099: ExpressionFunctionURIs.J_startsWithInsensitive,
100: content) {
101: protected final String lowerContent = content
102: .toLowerCase();
103:
104: public boolean evalBool(String l, String r) {
105: return l.toLowerCase().startsWith(lowerContent);
106: }
107: };
108: } else {
109: return new DyadicLiteral(L,
110: ExpressionFunctionURIs.J_startsWith, content) {
111: public boolean evalBool(String l, String r) {
112: return l.startsWith(r);
113: }
114: };
115: }
116: }
117:
118: public static Expression contains(Expression L,
119: final String content, String modifiers) {
120: if (modifiers.equals("i")) {
121: return new DyadicLiteral(L,
122: ExpressionFunctionURIs.J_containsInsensitive,
123: content) {
124: protected final String lowerContent = content
125: .toLowerCase();
126:
127: public boolean evalBool(String l, String r) {
128: return l.toLowerCase().indexOf(lowerContent) > -1;
129: }
130: };
131: } else {
132: return new DyadicLiteral(L,
133: ExpressionFunctionURIs.J_contains, content) {
134: public boolean evalBool(String l, String r) {
135: return l.indexOf(r) > -1;
136: }
137: };
138: }
139: }
140:
141: public static boolean notSpecial(String pattern) {
142: return pattern.matches("[A-Za-z0-9-_:/ ]*");
143: }
144:
145: public static boolean isContains(PatternLiteral pattern) {
146: return notSpecial(pattern.getPatternString())
147: && iOnly(pattern.getPatternModifiers());
148: }
149:
150: protected static boolean iOnly(String modifiers) {
151: return modifiers.equals("") || modifiers.equals("i");
152: }
153:
154: public static boolean isStartsWith(PatternLiteral pattern) {
155: String s = pattern.getPatternString();
156: return s.startsWith("^") && notSpecial(s.substring(1));
157: }
158:
159: public static boolean isEndsWith(PatternLiteral pattern) {
160: String s = pattern.getPatternString();
161: return s.endsWith("$")
162: && notSpecial(s.substring(0, s.length() - 1));
163: }
164:
165: }
166:
167: /*
168: (c) Copyright 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
169: All rights reserved.
170:
171: Redistribution and use in source and binary forms, with or without
172: modification, are permitted provided that the following conditions
173: are met:
174:
175: 1. Redistributions of source code must retain the above copyright
176: notice, this list of conditions and the following disclaimer.
177:
178: 2. Redistributions in binary form must reproduce the above copyright
179: notice, this list of conditions and the following disclaimer in the
180: documentation and/or other materials provided with the distribution.
181:
182: 3. The name of the author may not be used to endorse or promote products
183: derived from this software without specific prior written permission.
184:
185: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
186: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
187: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
188: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
189: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
190: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
191: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
192: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
193: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
194: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
195: */
|