001: /*
002: * Copyright 2004-2007 Gary Bentley
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may
005: * not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
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: package org.josql.contrib;
016:
017: import java.io.File;
018:
019: import org.apache.tools.ant.types.selectors.ExtendFileSelector;
020:
021: import org.apache.tools.ant.types.Parameter;
022:
023: import org.apache.tools.ant.BuildException;
024:
025: import org.josql.Query;
026:
027: /**
028: * A custom file selector for use with Ant.
029: * <p>
030: * See: <a target="_blank" href="http://ant.apache.org/manual/CoreTypes/selectors.html#customselect">Custom Ant Selectors</a> for more details.
031: * <p>
032: * Allows a JoSQL <a href="http://josql.sourceforge.net/manual/3-5.html" target="_blank">WHERE clause</a>
033: * to be applied to each file passed to the selector {@link #isSelected(File,String,File)}.
034: * <p>
035: * An obvious question to ask here is "why do I need this when Ant has lots of custom file selectors".
036: * Well, in short, you don't "need" this selector, but I've found that trying to remember all the
037: * custom elements and their attributes can be painful and doesn't give me all the power needed to
038: * select the files I want. This custom selector however does.
039: * <p>
040: * The selector supports the following "param"s.
041: * <ul>
042: * <li><b>where</b> - multiple <b>where</b> params are supported, the value of each param is concatenated
043: * with the others to form the full WHERE clause. It is up to you to decide how you split up
044: * your where clause.</li>
045: * <li><b>debug</b> - when set to <b>on</b> (case-insensitive) debug information about the WHERE clause
046: * actually used and for each file passed to {@link #isSelected(File,String,File)} what the
047: * WHERE clause evaluated to, either <code>true</code> or <code>false</code>.</li>
048: * </ul>
049: * <p>
050: * Usage:
051: * <p>
052: * A typical usage may be:
053: * <p>
054: * <pre>
055: * <fileset dir="myDir"
056: * includes="**">
057: * <custom classpath="[PATH_TO_JOSQL]/JoSQL-1.0.jar:[PATH_TO_JOSQL]/3rd-party-jars/gentlyWEB-utils-1.1.jar"
058: * classname="org.josql.contrib.JoSQLAntFileSelector">
059: * <param name="debug" value="on" />
060: * <param name="where" value="toDate (lastModified) > toDate ('22/Sep/2005')" />
061: * <param name="where" value="AND length > 10000" />
062: * </custom>
063: * </fileset>
064: * </pre>
065: * <p>
066: * This will create a file set containing all the files modified after 22/Sep/2005 and have a length greater
067: * than 10000 bytes.
068: * <p>
069: * Compare this to how it would be "normally" be done with standard Ant fileset selectors:
070: * <pre>
071: * <fileset dir="myDir"
072: * includes="**">
073: * <date datetime="22/Sep/2005"
074: * pattern="dd/MMM/yyyy"
075: * when="after" />
076: * <size value="10000"
077: * when="more" />
078: * </fileset>
079: * </pre>
080: * <p>
081: * Of course it is perfectly possible to mix and match this selector and other custom selectors or
082: * the built-in selectors.
083: */
084: public class JoSQLAntFileSelector extends Query implements
085: ExtendFileSelector {
086:
087: private static String sqlPrefix = "SELECT * FROM java.io.File WHERE ";
088:
089: public static final String WHERE = "where";
090: public static final String DEBUG = "debug";
091:
092: private Exception parseExp = null;
093: private boolean configured = false;
094: private String where = null;
095: private boolean debug = false;
096: private boolean shownWhere = false;
097:
098: public JoSQLAntFileSelector() {
099:
100: }
101:
102: public void setParameters(Parameter[] parms) {
103:
104: if (parms != null) {
105:
106: StringBuffer buf = new StringBuffer();
107:
108: for (int i = 0; i < parms.length; i++) {
109:
110: Parameter p = parms[i];
111:
112: if (p.getName().toLowerCase().equals(
113: JoSQLAntFileSelector.DEBUG)) {
114:
115: if (p.getValue().toLowerCase().equals("on")) {
116:
117: this .debug = true;
118:
119: }
120:
121: }
122:
123: if (p.getName().toLowerCase().equals(
124: JoSQLAntFileSelector.WHERE)) {
125:
126: if (buf.length() > 0) {
127:
128: buf.append(" ");
129:
130: }
131:
132: buf.append(p.getValue().trim());
133:
134: }
135:
136: }
137:
138: if (buf.length() > 0) {
139:
140: try {
141:
142: this .where = buf.toString();
143:
144: this .parse(JoSQLAntFileSelector.sqlPrefix
145: + buf.toString());
146:
147: this .configured = true;
148:
149: } catch (Exception e) {
150:
151: this .parseExp = e;
152:
153: }
154:
155: }
156:
157: }
158:
159: }
160:
161: public boolean isSelected(File basedir, String filename, File file)
162: throws BuildException {
163:
164: if (!this .configured) {
165:
166: if (this .parseExp != null) {
167:
168: throw new BuildException(
169: "Unable to init query with where clause: "
170: + this .where + ", reason: "
171: + this .parseExp.getMessage(),
172: this .parseExp);
173:
174: }
175:
176: throw new BuildException(
177: "Selector is not configured, expected to find a parameter with name: "
178: + JoSQLAntFileSelector.WHERE
179: + " that provides the where clause to evaluate against each file.");
180:
181: }
182:
183: if (this .debug) {
184:
185: if (!this .shownWhere) {
186:
187: System.out.println("Using WHERE clause: " + this .where);
188:
189: this .shownWhere = true;
190:
191: }
192:
193: }
194:
195: try {
196:
197: boolean v = this .getWhereClause().isTrue(file, this );
198:
199: if (this .debug) {
200:
201: System.out.println("WHERE = " + v + " for file: "
202: + file);
203:
204: }
205:
206: return v;
207:
208: } catch (Exception e) {
209:
210: //e.printStackTrace ();
211:
212: throw new BuildException("Unable to execute where clause: "
213: + this .getWhereClause() + " on file: " + file
214: + ", reason: " + e.getMessage(), e);
215:
216: }
217:
218: }
219:
220: }
|