001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.refactoring.java;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.Arrays;
047: import java.util.Collection;
048: import java.util.LinkedList;
049: import java.util.List;
050: import java.util.Map;
051: import java.util.TreeMap;
052: import org.netbeans.junit.diff.LineDiff;
053: import org.netbeans.modules.refactoring.api.AbstractRefactoring;
054: import org.netbeans.modules.refactoring.api.Problem;
055: import org.netbeans.modules.refactoring.api.RefactoringElement;
056: import org.netbeans.modules.refactoring.api.RefactoringSession;
057: import org.openide.filesystems.FileObject;
058: import org.openide.filesystems.FileUtil;
059:
060: /**
061: *
062: * @author Jiri Prox
063: */
064: public abstract class RefactoringTestCase extends LogTestCase {
065:
066: /**
067: * Map of files involved in refactoring. Files are stored as Strings as FQN + extension.
068: */
069: private Map<String, LinkedList<String>> refactoredFiles;
070:
071: /**
072: * List of source files (and folders) in project before performing refactoring. Names stored as FQN + extension
073: */
074: private List<String> projectSources;
075:
076: /** Creates a new instance of DummyTest
077: * @param name Name of current test
078: */
079: public RefactoringTestCase(String name) {
080: super (name);
081: }
082:
083: protected void addRefactoringElement(RefactoringElement element) {
084: FileObject fo = element.getParentFile();
085: String relPath = getRelativeFileName(fo);
086: if (!refactoredFiles.keySet().contains(relPath)) { //new file
087: try {
088: File fBackUp = new File(getWorkDir(),
089: getRelativeFileName(fo));
090: File oFile = FileUtil.toFile(fo);
091: if (!oFile.isDirectory())
092: copyFile(oFile, fBackUp);
093: } catch (IOException ioe) {
094: fail(ioe.getMessage());
095: }
096: refactoredFiles.put(relPath, new LinkedList<String>());
097: }
098: List<String> list = refactoredFiles.get(relPath);
099: list.add(element.getDisplayText());
100: }
101:
102: protected void dumpRefactoredFiles() {
103: for (String fileName : refactoredFiles.keySet()) {
104: ref(fileName);
105: ref("--------------------");
106: for (String text : refactoredFiles.get(fileName)) {
107: ref(text);
108: }
109: ref("--------------------");
110: try {
111: File actualFile = new File(classPathWorkDir,
112: fqn2FilePath(fileName));
113: File backupedFile = new File(getWorkDir(), fileName);
114: if (backupedFile.exists()) {
115: log("Original file:");
116: log(backupedFile);
117: }
118: if (!actualFile.exists()) {
119: ref("File was deleted");
120: } else {
121: log("Actual file:");
122: log(actualFile);
123: File diff = File
124: .createTempFile("refactoring", null);
125: LineDiff ldiff = new LineDiff();
126: ldiff.diff(actualFile, backupedFile, diff);
127: ref(diff);
128: diff.delete();
129: }
130: ref("\n");
131: } catch (IOException ioe) {
132: fail(ioe.getMessage());
133: }
134: }
135: }
136:
137: /**
138: * Compares two list of sources and dumps a new files
139: * @param originalSources Original projects sources
140: * @param currentSources New projects sources
141: */
142: protected void dumpNewFiles(List<String> originalSources,
143: List<String> currentSources) {
144: log("Original sources: " + originalSources);
145: log("Current sources: " + currentSources);
146: for (String fileName : currentSources) {
147: if (!originalSources.contains(fileName)) {
148: File file = new File(classPathWorkDir,
149: fqn2FilePath(fileName));
150: ref(fileName);
151: ref("--------------------");
152: if (file.isDirectory())
153: ref("Directory created");
154: else
155: ref(file);
156: ref("\n");
157: }
158: }
159: }
160:
161: private void dumpDir(File dir, List<String> result) {
162: File[] files = dir.listFiles();
163: Arrays.sort(files);
164: for (int i = 0; i < files.length; i++) {
165: File file = files[i];
166: if (file.getName().startsWith("."))
167: continue; // skipping hidden files
168: result
169: .add(getRelativeFileName(FileUtil
170: .toFileObject(file)));
171: if (file.isDirectory())
172: dumpDir(file, result);
173: }
174: }
175:
176: private List<String> getProjectSources() {
177: List<String> list = new LinkedList<String>();
178: dumpDir(classPathWorkDir, list);
179: return list;
180: }
181:
182: private String fqn2FilePath(String pkg) {
183: if (pkg.endsWith(".java")) {
184: String cutExtension = pkg.substring(0, pkg.length() - 5);
185: return cutExtension.replace('.', '/') + ".java";
186: } else {
187: return pkg.replace('.', '/');
188: }
189: }
190:
191: public boolean perform(AbstractRefactoring absRefactoring,
192: ParameterSetter parameterSetter) {
193: refactoredFiles = new TreeMap<String, LinkedList<String>>();
194: projectSources = getProjectSources();
195: Problem problem = absRefactoring.preCheck();
196: boolean fatal = false;
197: while (problem != null) {
198: ref(problem.getMessage());
199: fatal = fatal || problem.isFatal();
200: problem = problem.getNext();
201: }
202: if (fatal)
203: return false;
204: parameterSetter.setParameters();
205: problem = absRefactoring.fastCheckParameters();
206: while (problem != null) {
207: ref(problem.getMessage());
208: fatal = fatal || problem.isFatal();
209: problem = problem.getNext();
210: }
211: if (fatal)
212: return false;
213: problem = absRefactoring.checkParameters();
214: while (problem != null) {
215: ref(problem.getMessage());
216: fatal = fatal || problem.isFatal();
217: problem = problem.getNext();
218: }
219: if (fatal)
220: return false;
221: RefactoringSession rs = RefactoringSession.create("Session");
222: try {
223: absRefactoring.prepare(rs);
224: Collection<RefactoringElement> elems = rs
225: .getRefactoringElements();
226: for (RefactoringElement refactoringElement : elems) {
227: addRefactoringElement(refactoringElement);
228: }
229: rs.doRefactoring(true);
230: dumpRefactoredFiles();
231: dumpNewFiles(projectSources, getProjectSources());
232: } catch (Throwable t) {
233: t.printStackTrace();
234: t.printStackTrace(log);
235: }
236: return true;
237: }
238:
239: }
|