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-2007 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: package org.netbeans.modules.refactoring.java.plugins;
042:
043: import com.sun.source.tree.CompilationUnitTree;
044: import java.io.IOException;
045: import java.net.URL;
046: import java.text.MessageFormat;
047: import java.util.Collection;
048: import java.util.Collections;
049: import org.netbeans.api.java.source.CancellableTask;
050: import org.netbeans.api.java.source.CompilationController;
051: import org.netbeans.api.java.source.JavaSource;
052: import org.netbeans.api.java.source.ModificationResult;
053: import org.netbeans.api.java.source.WorkingCopy;
054: import org.netbeans.api.project.FileOwnerQuery;
055: import org.netbeans.modules.refactoring.api.Problem;
056: import org.netbeans.modules.refactoring.api.SingleCopyRefactoring;
057: import org.netbeans.modules.refactoring.java.RetoucheUtils;
058: import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
059: import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
060: import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
061: import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
062: import org.openide.ErrorManager;
063: import org.openide.filesystems.FileObject;
064: import org.openide.filesystems.URLMapper;
065: import org.openide.text.PositionBounds;
066: import org.openide.util.Lookup;
067: import org.openide.util.NbBundle;
068: import org.openide.util.Utilities;
069:
070: /** Plugin that implements the core functionality of Copy Class Refactoring.
071: *
072: * @author Jan Becicka
073: */
074: public class CopyClassRefactoringPlugin extends JavaRefactoringPlugin {
075: /** Reference to the parent refactoring instance */
076: private final SingleCopyRefactoring refactoring;
077:
078: /** Creates a new instance of PullUpRefactoringPlugin
079: * @param refactoring Parent refactoring instance.
080: */
081: CopyClassRefactoringPlugin(SingleCopyRefactoring refactoring) {
082: this .refactoring = refactoring;
083: }
084:
085: protected JavaSource getJavaSource(Phase p) {
086: return JavaSource.forFileObject(refactoring
087: .getRefactoringSource().lookup(FileObject.class));
088: }
089:
090: @Override
091: public Problem fastCheckParameters(CompilationController info) {
092: if (!Utilities.isJavaIdentifier(refactoring.getNewName())) {
093: String msg = new MessageFormat(NbBundle.getMessage(
094: CopyClassRefactoringPlugin.class,
095: "ERR_InvalidIdentifier"))
096: .format(new Object[] { refactoring.getNewName() });
097: return createProblem(null, true, msg);
098: }
099: URL target = refactoring.getTarget().lookup(URL.class);
100: String targetPackageName = RetoucheUtils.getPackageName(target);
101: if (!RetoucheUtils.isValidPackageName(targetPackageName)) {
102: String msg = new MessageFormat(NbBundle.getMessage(
103: CopyClassRefactoringPlugin.class,
104: "ERR_InvalidPackage"))
105: .format(new Object[] { targetPackageName });
106: return createProblem(null, true, msg);
107: }
108: String name = targetPackageName.replace('.', '/') + '/'
109: + refactoring.getNewName() + ".java"; // NOI18N
110: FileObject fo = URLMapper.findFileObject(target);
111: if (fo == null) {
112: return null;
113: }
114: if (fo.getFileObject(refactoring.getNewName(), (refactoring
115: .getRefactoringSource().lookup(FileObject.class))
116: .getExt()) != null)
117: return createProblem(null, true, new MessageFormat(NbBundle
118: .getMessage(CopyClassRefactoringPlugin.class,
119: "ERR_ClassToMoveClashes"))
120: .format(new Object[] { refactoring.getNewName() }));
121: return null;
122: }
123:
124: @Override
125: public Problem checkParameters() {
126: return null;
127: }
128:
129: @Override
130: public Problem preCheck() {
131: return null;
132: }
133:
134: public Problem prepare(RefactoringElementsBag refactoringElements) {
135: refactoringElements.add(refactoring, new CopyClass());
136: return null;
137: }
138:
139: private class CopyClass extends
140: SimpleRefactoringElementImplementation implements
141: RefactoringElementImplementation {
142:
143: public CopyClass() {
144: }
145:
146: public String getText() {
147: return getDisplayText();
148: }
149:
150: public String getDisplayText() {
151: return new MessageFormat(NbBundle.getMessage(
152: CopyClassRefactoringPlugin.class,
153: "TXT_CopyClassToPackage")).format( // NOI18N
154: new Object[] { refactoring.getNewName(),
155: getTargetPackageName(),
156: getParentFile().getName() });
157: }
158:
159: public Lookup getLookup() {
160: return Lookup.EMPTY;
161: }
162:
163: public PositionBounds getPosition() {
164: return null;
165: }
166:
167: public String getTargetPackageName() {
168: return RetoucheUtils.getPackageName(refactoring.getTarget()
169: .lookup(URL.class));
170: }
171:
172: public void performChange() {
173: try {
174: FileObject fo = RetoucheUtils
175: .getOrCreateFolder(refactoring.getTarget()
176: .lookup(URL.class));
177: FileObject source = refactoring.getRefactoringSource()
178: .lookup(FileObject.class);
179: String oldPackage = RetoucheUtils.getPackageName(source
180: .getParent());
181:
182: FileObject newOne = refactoring.getContext().lookup(
183: FileObject.class);
184: final Collection<ModificationResult> results = processFiles(
185: Collections.singleton(newOne),
186: new UpdateReferences(
187: !fo.equals(source.getParent())
188: && FileOwnerQuery
189: .getOwner(fo)
190: .equals(
191: FileOwnerQuery
192: .getOwner(source)),
193: oldPackage, source.getName()));
194: results.iterator().next().commit();
195: } catch (Exception ioe) {
196: ErrorManager.getDefault().notify(ioe);
197: }
198:
199: }
200:
201: public FileObject getParentFile() {
202: return refactoring.getRefactoringSource().lookup(
203: FileObject.class);
204: }
205: }
206:
207: private class UpdateReferences implements
208: CancellableTask<WorkingCopy> {
209:
210: private boolean insertImport;
211: private String oldPackage;
212: private String oldName;
213:
214: public UpdateReferences(boolean insertImport,
215: String oldPackage, String oldName) {
216: this .insertImport = insertImport;
217: this .oldPackage = oldPackage;
218: this .oldName = oldName;
219:
220: }
221:
222: public void cancel() {
223: }
224:
225: public void run(WorkingCopy compiler) throws IOException {
226: compiler.toPhase(JavaSource.Phase.RESOLVED);
227: CompilationUnitTree cu = compiler.getCompilationUnit();
228: if (cu == null) {
229: ErrorManager.getDefault().log(
230: ErrorManager.ERROR,
231: "compiler.getCompilationUnit() is null "
232: + compiler); // NOI18N
233: return;
234: }
235:
236: CopyTransformer findVisitor = new CopyTransformer(compiler,
237: oldName, refactoring.getNewName(), insertImport,
238: oldPackage);
239: findVisitor.scan(compiler.getCompilationUnit(), null);
240: }
241: }
242: }
|