001: /* ====================================================================
002: * The JRefactory License, Version 1.0
003: *
004: * Copyright (c) 2001 JRefactory. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by the
021: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "JRefactory" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please contact seguin@acm.org.
028: *
029: * 5. Products derived from this software may not be called "JRefactory",
030: * nor may "JRefactory" appear in their name, without prior written
031: * permission of Chris Seguin.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of JRefactory. For more information on
049: * JRefactory, please see
050: * <http://www.sourceforge.org/projects/jrefactory>.
051: */
052: package org.acm.seguin.ant;
053:
054: import java.io.*;
055: import java.util.*;
056:
057: import org.apache.tools.ant.*;
058: import org.apache.tools.ant.types.*;
059:
060: import org.acm.seguin.awt.ExceptionPrinter;
061: import org.acm.seguin.awt.TextExceptionPrinter;
062: import org.acm.seguin.util.FileSettings;
063: import net.sourceforge.jrefactory.factory.FileParserFactory;
064: import org.acm.seguin.pretty.PrettyPrintFile;
065: import org.apache.tools.ant.taskdefs.FixCRLF;
066:
067: /**
068: *@author Ara Abrahamian (ara_e@email.com)
069: *@created May 18, 2001
070: *@version $Revision: 1.10 $
071: */
072: public final class Pretty extends Task {
073: private CVSUtil cvsUtil = new CVSUtil();
074: private Vector filesets = new Vector();
075: private boolean cvs = false;
076: private File compileDir;
077:
078: /**
079: * Sets the cvs attribute of the Pretty object
080: *
081: *@param cvs The new cvs value
082: */
083: public void setCvs(boolean cvs) {
084: this .cvs = cvs;
085: }
086:
087: /**
088: * Sets the settingsdir attribute of the Pretty object
089: *
090: *@param new_settings_dir The new settingsdir value
091: */
092: public void setSettingsdir(File new_settings_dir) {
093: FileSettings.setSettingsRoot(new_settings_dir);
094: }
095:
096: public File getCompileDir() {
097: return compileDir;
098: }
099:
100: public void setCompileDir(File compileDir) {
101: this .compileDir = compileDir;
102: }
103:
104: /**
105: * Sets the timeZone attribute of the Pretty object
106: *
107: * @param timeZone The new timeZone value
108: */
109: public void setTimeZone(String timeZone) {
110: cvsUtil.setTimeZone(timeZone);
111: }
112:
113: /**
114: * Adds a set of files (nested fileset attribute).
115: *
116: *@param set The feature to be added to the Fileset attribute
117: */
118: public void addFileset(FileSet set) {
119: filesets.addElement(set);
120: }
121:
122: /**
123: * Description of the Method
124: *
125: *@exception BuildException Description of the Exception
126: */
127: public void execute() throws BuildException {
128: // make sure we don't have an illegal set of options
129: validateAttributes();
130: File source_file = null;
131:
132: try {
133: ExceptionPrinter.register(new TextExceptionPrinter());
134: PrettyPrintFile ppf = new PrettyPrintFile();
135: FixCRLF fixcrlf_task = (FixCRLF) project
136: .createTask("fixcrlf");
137:
138: configureFixCrlfTask(fixcrlf_task);
139:
140: ppf.setAsk(false);
141:
142: for (int i = 0; i < filesets.size(); i++) {
143: FileSet fs = (FileSet) filesets.elementAt(i);
144: DirectoryScanner ds = fs.getDirectoryScanner(project);
145: File from_dir = fs.getDir(project);
146: String[] src_files = ds.getIncludedFiles();
147:
148: for (int j = 0; j < src_files.length; j++) {
149: source_file = new File(from_dir, src_files[j]);
150:
151: if (shouldBeautify(source_file, from_dir)) {
152: System.out.println("formatting:" + source_file);
153: ppf.setParserFactory(new FileParserFactory(
154: source_file));
155:
156: // reformat
157: ppf.apply(source_file);
158:
159: fixcrlf_task.setSrcdir(from_dir);
160: fixcrlf_task.setIncludesfile(source_file);
161: fixcrlf_task.execute();
162: }
163: }
164: }
165: } catch (Exception ex) {
166: ex.printStackTrace();
167:
168: throw new BuildException("Cannot javastyle file="
169: + source_file, location);
170: }
171: }
172:
173: private void configureFixCrlfTask(FixCRLF fixcrlf_task) {
174: fixcrlf_task.setOwningTarget(getOwningTarget());
175: FixCRLF.CrLf eol = new FixCRLF.CrLf();
176: FileSettings prettySettings = FileSettings
177: .getRefactoryPrettySettings();
178: String lineEnding = prettySettings.getString("end.line");
179: if (lineEnding == null || lineEnding.length() == 0) {
180: lineEnding = "cr";
181: }
182: eol.setValue(lineEnding.toLowerCase());
183: fixcrlf_task.setEol(eol);
184: }
185:
186: private boolean shouldBeautify(File source_file, File from_dir) {
187: //if read-only, then we can't beautify it anyway
188: if (source_file.canWrite() == false)
189: return false;
190:
191: //if cvs parameter is false
192: if (cvs == false)
193: return sourceModifiedAfterLastCompile(source_file, from_dir);
194:
195: //if not cvs-modified
196: if (cvsUtil.isFileModified(source_file) == false)
197: return false;
198:
199: return sourceModifiedAfterLastCompile(source_file, from_dir);
200: }
201:
202: private boolean sourceModifiedAfterLastCompile(File source_file,
203: File from_dir) {
204: //if compileDir parameter not specified, then we can't check for
205: //modified date of source file against the compiled one
206: if (compileDir == null)
207: return true;
208:
209: //calc absolute paths so that we're sure we're comparing correct unique files
210: String source_file_path = source_file.getAbsoluteFile()
211: .toString();
212: String compile_dir_path = compileDir.getAbsoluteFile()
213: .toString();
214: String from_dir_path = from_dir.getAbsoluteFile().toString();
215:
216: String source_file_name_from_dir = source_file_path
217: .substring(from_dir_path.length());
218: String source_file_name_wo_ext = source_file_name_from_dir
219: .substring(0, source_file_name_from_dir
220: .lastIndexOf('.'));
221:
222: //now get the respective compiled file for the source file
223: String compiled_file_name_from_dir = source_file_name_wo_ext
224: + ".class";
225: String compiled_file_name = compile_dir_path
226: + compiled_file_name_from_dir;
227: File compiled_file = new File(compiled_file_name);
228:
229: //not found, probably not compiled before, beautify
230: if (compiled_file.exists() == false)
231: return true;
232:
233: //since we put <pretty/> before <javac/>, <javac/> sets modification
234: //date to a date bigger than that of source file when compiling it
235: if (compiled_file.lastModified() > source_file.lastModified())
236: return false;
237:
238: return true;
239: }
240:
241: /**
242: * Ensure we have a consistent and legal set of attributes, and set any
243: * internal flags necessary based on different combinations of attributes.
244: *
245: *@exception BuildException Description of the Exception
246: */
247: protected void validateAttributes() throws BuildException {
248: if (filesets.size() == 0) {
249: throw new BuildException("Specify at least one fileset.");
250: }
251:
252: //possibly some other attributes: overwrite/destDir/etc
253: }
254: }
255: // EOF
|