1 /*2 * The contents of this file are subject to the terms of the Common Development3 * and Distribution License (the License). You may not use this file except in4 * compliance with the License.5 *6 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html7 * or http://www.netbeans.org/cddl.txt.8 * 9 * When distributing Covered Code, include this CDDL Header Notice in each file10 * and include the License file at http://www.netbeans.org/cddl.txt.11 * If applicable, add the following below the CDDL Header, with the fields12 * enclosed by brackets [] replaced by your own identifying information:13 * "Portions Copyrighted [year] [name of copyright owner]"14 *15 * The Original Software is NetBeans. The Initial Developer of the Original16 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun17 * Microsystems, Inc. All Rights Reserved.18 */19 package org.netbeans.modules.refactoring.java.plugins;20 21 import org.netbeans.modules.refactoring.api.Problem;22 import org.netbeans.modules.refactoring.java.api.PushDownRefactoring;23 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;24 25 26 /**27 * Plugin that implements the core functionality of Push Down refactoring.28 *29 * @author Pavel Flaska30 */31 public class PushDownRefactoringPlugin extends JavaRefactoringPlugin {32 33 /** Reference to the parent refactoring instance */34 private final PushDownRefactoring refactoring;35 36 /** Creates a new instance of PushDownRefactoringPlugin */37 public PushDownRefactoringPlugin(PushDownRefactoring refactoring) {38 this.refactoring = refactoring;39 }40 41 public Problem preCheck() {42 throw new UnsupportedOperationException ("Not supported yet.");43 }44 45 public Problem checkParameters() {46 throw new UnsupportedOperationException ("Not supported yet.");47 }48 49 public Problem fastCheckParameters() {50 throw new UnsupportedOperationException ("Not supported yet.");51 }52 53 public Problem prepare(RefactoringElementsBag refactoringElements) {54 throw new UnsupportedOperationException ("Not supported yet.");55 }56 57 // /** 58 // * Checks pre-conditions of the refactoring.59 // * 60 // * @return problems found or <tt>null</tt>.61 // */62 // public Problem preCheck() {63 // // fire operation start on the registered progress listeners (3 steps)64 // fireProgressListenerStart(AbstractRefactoring.PRE_CHECK, 4);65 // try {66 // JavaClass sourceType = refactoring.getSourceType();67 // // check whether the element is valid68 // Problem result = isElementAvail(sourceType);69 // if (result != null) {70 // // fatal error -> don't continue with further checks71 // return result;72 // }73 // if (!CheckUtils.isElementInOpenProject(sourceType)) {74 // return new Problem(true, NbBundle.getMessage(JavaRefactoringPlugin.class, "ERR_ProjectNotOpened"));75 // }76 // 77 // // check whether the element is an unresolved class78 // if (sourceType instanceof UnresolvedClass) {79 // // fatal error -> return80 // return new Problem(true, NbBundle.getMessage(JavaRefactoringPlugin.class, "ERR_ElementNotAvailable")); // NOI18N81 // }82 // // increase progress (step 1)83 // fireProgressListenerStep();84 // if (refactoring.collectSubtypes().length == 0) {85 // return new Problem(true, NbBundle.getMessage(PushDownRefactoringPlugin.class, "ERR_PushDOwn_NoSubtype")); // NOI18N86 // }87 // // increase progress (step 2)88 // fireProgressListenerStep();89 // // #2 - check if there are any members to pull up90 // if (!hasMembers(sourceType)) {91 // // fatal error -> return92 // return new Problem(true, NbBundle.getMessage(PushDownRefactoringPlugin.class, "ERR_PushDown_NoMembers")); // NOI18N93 // }94 // // increase progress (step 3)95 // fireProgressListenerStep();96 // 97 // return null;98 // } finally {99 // fireProgressListenerStop();100 // }101 // }102 // 103 // public Problem fastCheckParameters() {104 // // #1 - check whether there are any members to pull up105 // if (refactoring.getMembers().length == 0) {106 // return new Problem(true, NbBundle.getMessage(PushDownRefactoringPlugin.class, "ERR_PushDown_NoMembersSelected")); // NOI18N107 // }108 // return null;109 // }110 // 111 // public Problem checkParameters() {112 // return null;113 // }114 // 115 // public Problem prepare(RefactoringElementsBag refactoringElements) {116 // PushDownRefactoring.MemberInfo[] members = refactoring.getMembers();117 // List featuresToMove = new ArrayList();118 // JavaClass[] subtypes = refactoring.collectSubtypes();119 // for (int i = 0; i < members.length; i++) {120 // // go through all subtypes where method should be copied121 // if (members[i].member instanceof Feature) {122 // featuresToMove.add(members[i].member);123 // }124 // for (int j = 0; j < subtypes.length; j++) {125 // boolean enabled = true;126 // for (Iterator it = subtypes[j].getFeatures().iterator(); it.hasNext();) {127 // Feature f = (Feature) it.next();128 // if (CheckUtils.membersEqual(f, members[i].member)) {129 // enabled = false;130 // break;131 // }132 // }133 // refactoringElements.add(refactoring, new CopyMemberElement(members[i].member, subtypes[j], 0, enabled));134 // UndoWatcher.watch(((JMManager) JMManager.getManager()).getDataObject(subtypes[j].getResource()));135 // }136 // // register remove element, which removes original method which137 // // will be copied to subtypes. If user checks make it abstract138 // // checkbox, the element will not remove the method, instead it,139 // // it will change method to be declared as abstract140 // refactoringElements.add(refactoring, new RemoveOriginalElement(members[i].member, members[i].makeAbstract));141 // }142 //143 // collectRelaxModifierElements(refactoring, refactoringElements, refactoring.getSourceType(), featuresToMove);144 // return null;145 // }146 // 147 // // --- REFACTORING ELEMENTS ------------------------------------------------148 // /** Refactoring element that takes care of moving an element to the target type.149 // */150 // private static class RemoveOriginalElement extends SimpleRefactoringElementImpl {151 // private final NamedElement elementToRemove;152 // private final String text;153 // private final boolean makeItAbstract;154 // 155 // RemoveOriginalElement(NamedElement elementToRemove, boolean makeItAbstract) {156 // this.elementToRemove = elementToRemove;157 // this.makeItAbstract = makeItAbstract;158 // this.text = NbBundle.getMessage(PushDownRefactoringPlugin.class, 159 // makeItAbstract ? "TXT_PushDown_Abstract": "TXT_PushDown_Remove", // NOI18N160 // UIUtilities.getDisplayText(elementToRemove));161 // }162 // 163 // public void performChange() {164 // if (makeItAbstract) {165 // Method m = (Method) elementToRemove;166 // m.setModifiers(m.getModifiers() | Modifier.ABSTRACT);167 // m.setBodyText(null);168 // } else169 // elementToRemove.refDelete();170 // }171 //172 // public String getText() {173 // return text;174 // }175 //176 // public PositionBounds getPosition() {177 // return JavaMetamodel.getManager().getElementPosition(elementToRemove);178 // }179 //180 // public FileObject getParentFile() {181 // return JavaMetamodel.getManager().getFileObject(elementToRemove.getResource());182 // }183 //184 // public Element getJavaElement() {185 // return (Element) elementToRemove.refImmediateComposite();186 // }187 //188 // public String getDisplayText() {189 // return text;190 // }191 // }192 // 193 // private static class CopyMemberElement extends SimpleRefactoringElementImpl {194 // private final NamedElement elementToCopy;195 // private final JavaClass target;196 // private final int newModifiers;197 // private final String text;198 // 199 // /**200 // * Creates a new instance of this refactoring element.201 // * @elementToCopy Element to be moved to the target type.202 // * @target The target type the element should be moved to.203 // * @newModifiers New modifiers of the element or 0 if the modifiers should204 // * remain unchanged.205 // */206 // CopyMemberElement(NamedElement elementToCopy, JavaClass target, int newModifiers, boolean enabled) {207 // this.elementToCopy = elementToCopy;208 // this.target = target;209 // this.newModifiers = newModifiers;210 // this.text = NbBundle.getMessage(PushDownRefactoringPlugin.class, "TXT_PushDown_Member", // NOI18N211 // UIUtilities.getDisplayText(elementToCopy),212 // UIUtilities.getDisplayText(target)); 213 // setEnabled(enabled);214 // }215 //216 // public void performChange() {217 // JavaModelPackage targetExtent = (JavaModelPackage) target.refImmediatePackage();218 // JavaClass elementParent;219 // Element newElement;220 // // processing is different for Feature (field, inner class, method)221 // // and MultipartId (interface in the implements clause)222 // if (elementToCopy instanceof Feature) {223 // // get the declaring class of the element224 // elementParent = (JavaClass) ((Feature) elementToCopy).getDeclaringClass();225 // // we need to create a copy of the element in the target extent226 // newElement = ((MetadataElement) elementToCopy).duplicate(targetExtent);227 // // add the element to the target class228 // target.getContents().add(newElement);229 // // change modifiers if necessary230 // if (newModifiers != 0) {231 // ((Feature) newElement).setModifiers(newModifiers);232 // }233 // } else {234 // // get parent type of the element235 // elementParent = (JavaClass) elementToCopy.refImmediateComposite();236 // newElement = ((MetadataElement) elementToCopy).duplicate(targetExtent);237 // // add the new element to the implements clause of the target type238 // target.getInterfaceNames().add(newElement);239 // }240 // ((MetadataElement) newElement).fixImports(target, elementToCopy);241 // }242 //243 // public String getText() {244 // return text;245 // }246 //247 // public String getDisplayText() {248 // return text;249 // }250 //251 // public FileObject getParentFile() {252 // return JavaMetamodel.getManager().getFileObject(elementToCopy.getResource());253 // }254 //255 // public Element getJavaElement() {256 // return target;257 // }258 //259 // public PositionBounds getPosition() {260 // return JavaMetamodel.getManager().getElementPosition(elementToCopy);261 // }262 // }263 // 264 // private static class RelaxAccessModifier extends SimpleRefactoringElementImpl {265 // private final String text;266 // private final Feature feature;267 // 268 // RelaxAccessModifier(Feature feature) {269 // this.feature = feature;270 // boolean isPrivate = Modifier.isPrivate(feature.getModifiers());271 // this.text = new MessageFormat(NbBundle.getMessage(PushDownRefactoringPlugin.class, "TXT_PushDown_RelaxAccessModifier")).format(272 // new Object[] {273 // isPrivate ? NbBundle.getMessage(PushDownRefactoringPlugin.class, "LBL_PushDown_private") : 274 // NbBundle.getMessage(PushDownRefactoringPlugin.class, "LBL_PushDown_package_private"),275 // NbBundle.getMessage(PushDownRefactoringPlugin.class, "LBL_PushDown_protected")276 // }277 // );278 // }279 // 280 // public void performChange() {281 // feature.setModifiers((feature.getModifiers() & ~Modifier.PRIVATE) | Modifier.PROTECTED);282 // }283 //284 // public String getText() {285 // return text;286 // }287 //288 // public String getDisplayText() {289 // return text;290 // }291 //292 // public FileObject getParentFile() {293 // return JavaMetamodel.getManager().getFileObject(feature.getResource());294 // }295 //296 // public Element getJavaElement() {297 // return feature;298 // }299 //300 // public PositionBounds getPosition() {301 // return JavaMetamodel.getManager().getElementPosition(feature);302 // }303 // }304 // 305 // // --- HELPER METHODS ------------------------------------------------------306 // 307 // // checks if the source type or any of its supertypes has any members that could308 // // be pushed down309 // private static boolean hasMembers(JavaClass sourceType, JavaClass[] supertypes) {310 // boolean result = hasMembers(sourceType);311 // 312 // for (int i = 0; i < (supertypes.length - 1) && !result; i++) {313 // result = hasMembers(supertypes[i]);314 // }315 // 316 // return result;317 // }318 // 319 // // checks if the passed type has any members that could be pushed down320 // private static boolean hasMembers(JavaClass type) {321 // for (Iterator it = type.getFeatures().iterator(); it.hasNext();) {322 // Feature feature = (Feature) it.next();323 // if (feature instanceof Field || feature instanceof Method || feature instanceof JavaClass) {324 // return true;325 // }326 // }327 // return false;328 // }329 //330 // static void collectRelaxModifierElements(AbstractRefactoring refactoring, RefactoringElementsBag refactoringElements, JavaClass jc, List members) {331 // Iterator iter;332 // Set accessedMembers = new HashSet();333 // Set membersToCheck = new HashSet();334 // Set membersToMove = new HashSet();335 // for (iter = members.iterator(); iter.hasNext(); ) {336 // membersToMove.add(iter.next());337 // }338 // for (iter = jc.getFeatures().iterator(); iter.hasNext(); ) {339 // Feature f = (Feature) iter.next();340 // int mods = f.getModifiers();341 // if (Modifier.isPrivate(mods) || (!Modifier.isProtected(mods) && !Modifier.isPublic(mods))) {342 // membersToCheck.add(f);343 // }344 // }345 // for (iter = membersToMove.iterator(); iter.hasNext(); ) {346 // traverseAccessedMembers((Feature) iter.next(), accessedMembers, membersToCheck);347 // }348 // for (iter = jc.getFeatures().iterator(); iter.hasNext(); ) {349 // Feature f = (Feature) iter.next();350 // if (accessedMembers.contains(f) && !membersToMove.contains(f)) {351 // refactoringElements.add(refactoring, new RelaxAccessModifier(f));352 // }353 // }354 // }355 // 356 // // computes which member elements from the 'membersToCheck' set are accessed by the passed 'element or some of its children357 // static void traverseAccessedMembers(Element element, Set accessedMembers, Set membersToCheck) {358 // if (element instanceof MethodInvocation || element instanceof VariableAccess || element instanceof TypeReference) {359 // NamedElement nelem = ((ElementReference) element).getElement();360 // if (membersToCheck.contains(nelem)) {361 // accessedMembers.add(nelem);362 // }363 // }364 // 365 // for (Iterator it = element.getChildren().iterator(); it.hasNext();) {366 // traverseAccessedMembers((Element) it.next(), accessedMembers, membersToCheck);367 // }368 // }369 // 370 }371