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:
042: package org.netbeans.modules.web.jsf.refactoring;
043:
044: import com.sun.source.tree.CompilationUnitTree;
045: import com.sun.source.tree.Tree;
046: import com.sun.source.tree.Tree.Kind;
047: import com.sun.source.util.TreePath;
048: import java.io.IOException;
049: import java.net.URL;
050: import java.util.ArrayList;
051: import java.util.Collection;
052: import java.util.List;
053: import java.util.logging.Level;
054: import java.util.logging.Logger;
055: import javax.lang.model.element.Element;
056: import javax.lang.model.element.TypeElement;
057: import org.netbeans.api.java.classpath.ClassPath;
058: import org.netbeans.api.java.source.CompilationController;
059: import org.netbeans.api.java.source.CompilationInfo;
060: import org.netbeans.api.java.source.JavaSource;
061: import org.netbeans.api.java.source.Task;
062: import org.netbeans.api.java.source.TreePathHandle;
063: import org.netbeans.api.project.FileOwnerQuery;
064: import org.netbeans.api.project.Project;
065: import org.netbeans.modules.refactoring.api.MoveRefactoring;
066: import org.netbeans.modules.refactoring.api.Problem;
067: import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
068: import org.netbeans.modules.refactoring.spi.RefactoringPlugin;
069: import org.netbeans.modules.web.api.webmodule.WebModule;
070: import org.openide.filesystems.FileObject;
071: import org.openide.filesystems.FileUtil;
072:
073: /**
074: *
075: * @author Petr Pisl
076: */
077: public class JSFMoveClassPlugin implements RefactoringPlugin {
078:
079: private Collection<TreePathHandle> treePathHandles;
080:
081: private static final Logger LOGGER = Logger
082: .getLogger(JSFMoveClassPlugin.class.getName());
083:
084: private final MoveRefactoring refactoring;
085:
086: public JSFMoveClassPlugin(MoveRefactoring refactoring) {
087: this .refactoring = refactoring;
088: }
089:
090: public Problem preCheck() {
091: return null;
092: }
093:
094: public Problem checkParameters() {
095: return null;
096: }
097:
098: public Problem fastCheckParameters() {
099: return null;
100: }
101:
102: public void cancelRequest() {
103:
104: }
105:
106: public Problem prepare(RefactoringElementsBag refactoringElements) {
107: Collection<? extends FileObject> fileObjects = refactoring
108: .getRefactoringSource().lookupAll(FileObject.class);
109: Collection treePathHandlesFromLookup = refactoring
110: .getRefactoringSource().lookupAll(TreePathHandle.class);
111: treePathHandles = new ArrayList(treePathHandlesFromLookup);
112:
113: if (fileObjects != null) {
114: for (FileObject fileObject : fileObjects) {
115: if (fileObject.isFolder()
116: && (JSFRefactoringUtils.isJavaFile(fileObject) || fileObject
117: .isFolder())) {
118: // moving folder
119: // find the old package name
120: ClassPath classPath = ClassPath.getClassPath(
121: fileObject, ClassPath.SOURCE);
122: FileObject root = classPath
123: .findOwnerRoot(fileObject);
124:
125: String prefix = FileUtil.getRelativePath(root,
126: fileObject.getParent()).replace('/', '.');
127: String oldName = (prefix.length() == 0 ? fileObject
128: .getName() : prefix + '.'
129: + fileObject.getName());
130: // the new package name
131: String newPrefix = JSFRefactoringUtils
132: .getPackageName(refactoring.getTarget()
133: .lookup(URL.class));
134: String newName = (newPrefix.length() == 0 ? fileObject
135: .getName()
136: : newPrefix + '.' + fileObject.getName());
137:
138: JSFRefactoringUtils.renamePackage(refactoring,
139: refactoringElements, fileObject, oldName,
140: newName, true);
141: } else {
142: if (JSFRefactoringUtils.isJavaFile(fileObject)) {
143: JavaSource source = JavaSource
144: .forFileObject(fileObject);
145: if (source != null) {
146: try {
147: source
148: .runUserActionTask(
149: new Task<CompilationController>() {
150: public void run(
151: CompilationController co)
152: throws Exception {
153: co
154: .toPhase(JavaSource.Phase.RESOLVED);
155: CompilationUnitTree cut = co
156: .getCompilationUnit();
157: List<? extends Tree> typeDecls = cut
158: .getTypeDecls();
159: if (!typeDecls
160: .isEmpty()) {
161: treePathHandles
162: .add(TreePathHandle
163: .create(
164: TreePath
165: .getPath(
166: cut,
167: typeDecls
168: .get(0)),
169: co));
170: refactoring
171: .getContext()
172: .add(
173: co);
174: }
175: }
176: }, false);
177: } catch (IllegalArgumentException ex) {
178: LOGGER
179: .log(
180: Level.WARNING,
181: "Exception in JSFMoveClassPlugin",
182: ex); //NOI18N
183: } catch (IOException ex) {
184: LOGGER
185: .log(
186: Level.WARNING,
187: "Exception in JSFMoveClassPlugin",
188: ex); //NOI18N
189: }
190: }
191: }
192: }
193: }
194: }
195:
196: if (treePathHandles != null) {
197: for (TreePathHandle treePathHandle : treePathHandles) {
198: if (treePathHandle != null
199: && treePathHandle.getKind() == Kind.CLASS) {
200: WebModule webModule = WebModule
201: .getWebModule(treePathHandle
202: .getFileObject());
203: if (webModule != null) {
204: CompilationInfo info = JSFRefactoringUtils
205: .getCompilationInfo(refactoring,
206: treePathHandle.getFileObject());
207: if (info != null) {
208: Element resElement = treePathHandle
209: .resolveElement(info);
210: TypeElement type = (TypeElement) resElement;
211: String oldFQN = type.getQualifiedName()
212: .toString();
213: String newPackageName = JSFRefactoringUtils
214: .getPackageName(refactoring
215: .getTarget().lookup(
216: URL.class));
217: String newFQN = newPackageName.length() == 0 ? type
218: .getSimpleName().toString()
219: : newPackageName
220: + '.'
221: + type.getSimpleName()
222: .toString();
223: if (isTargetOtherProject(treePathHandle
224: .getFileObject(), refactoring)) {
225: List<Occurrences.OccurrenceItem> items = Occurrences
226: .getAllOccurrences(webModule,
227: oldFQN, newFQN);
228: for (Occurrences.OccurrenceItem item : items) {
229: refactoringElements
230: .add(
231: refactoring,
232: new JSFSafeDeletePlugin.JSFSafeDeleteClassElement(
233: item));
234: }
235: } else {
236: List<Occurrences.OccurrenceItem> items = Occurrences
237: .getAllOccurrences(webModule,
238: oldFQN, newFQN);
239: Modifications modification = new Modifications();
240: for (Occurrences.OccurrenceItem item : items) {
241: Modifications.Difference difference = new Modifications.Difference(
242: Modifications.Difference.Kind.CHANGE,
243: item.getChangePosition()
244: .getBegin(),
245: item.getChangePosition()
246: .getEnd(),
247: item.getOldValue(),
248: item.getNewValue(),
249: item
250: .getRenamePackageMessage());
251: modification.addDifference(item
252: .getFacesConfig(),
253: difference);
254: refactoringElements
255: .add(
256: refactoring,
257: new DiffElement.ChangeFQCNElement(
258: difference,
259: item,
260: modification));
261: }
262: }
263: }
264: }
265: }
266: }
267: }
268: return null;
269: }
270:
271: private boolean isTargetOtherProject(FileObject localFileObject,
272: MoveRefactoring ref) {
273: boolean targetOtherProject = false;
274:
275: try {
276: Project targetProject = FileOwnerQuery.getOwner(ref
277: .getTarget().lookup(URL.class).toURI());
278: Project srcProject = FileOwnerQuery
279: .getOwner(localFileObject);
280: targetOtherProject = !targetProject.equals(srcProject);
281: } catch (Exception e) {
282: LOGGER.log(Level.WARNING,
283: "Exception in JSFMoveClassPlugin", e); //NOI18N
284: }
285:
286: return targetOtherProject;
287: }
288: }
|