001: /**
002: *
003: */package core;
004:
005: import java.util.Iterator;
006: import java.util.List;
007:
008: import logging.LoggingPlugin;
009:
010: import org.eclipse.core.runtime.ILog;
011: import org.eclipse.core.runtime.IPath;
012: import org.eclipse.core.runtime.IStatus;
013: import org.eclipse.core.runtime.Status;
014: import org.eclipse.jdt.core.ICompilationUnit;
015: import org.eclipse.jdt.core.IJavaElement;
016: import org.eclipse.jdt.core.IJavaProject;
017: import org.eclipse.jdt.core.IPackageFragment;
018: import org.eclipse.jdt.core.JavaModelException;
019: import org.eclipse.jdt.internal.core.PackageFragmentRoot;
020:
021: /**
022: * This class is used by a implementation refactoring. It adapts the
023: * source code to the change of the model implementation property.
024: * If the class name of the implementation should be changed this
025: * method renames the concerning compilation unit. If the packages
026: * of the implementation are different, packages will be created
027: * if necessary and the compilation unit will be moved.
028: * @author sh
029: *
030: */
031: public class RenameImplementation extends AbstractAST implements
032: ICodeRefactoring {
033:
034: // the Info Object containing all necessary model info
035: private ModelInfo info = null;
036:
037: /**
038: * Renames the given compilation unit.
039: * It automatically renames the class file name
040: * and also the type name.
041: *
042: * @param modelElement the compilatin unit to rename
043: * @see refactor.core.IRefactoring#modification(org.eclipse.jdt.core.IJavaElement)
044: */
045: @SuppressWarnings({"restriction"})
046: public void modification(IJavaElement modelElement) {
047: // check if a Compilation Unit should be modified
048: if (modelElement instanceof ICompilationUnit == false)
049: return;
050:
051: // get the packages of the info object
052: String newPackagename = Util.packagename(info
053: .getNewImplementation());
054: String oldPackagename = Util.packagename(info
055: .getOldImplementation());
056:
057: // check if the type should stay in the same package
058: // if the packages are the same, just perfom a renaming
059: if (newPackagename.equals(oldPackagename)) {
060: renameCompilationUnit(modelElement);
061: }
062:
063: // if the packages are different
064: // check if the new package already exist. If so just move the cu
065: // otherwise if the new package doesn't exist, create it.
066: /*
067: else {
068: try {
069: ICompilationUnit unit = (ICompilationUnit)modelElement;
070: IProject project = unit.getCorrespondingResource().getProject();
071: IJavaProject javaProject = JavaCore.create(project);
072:
073: IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
074: for (int i = 0; i < roots.length; i++) {
075: IPackageFragmentRoot packageFragmentRoot = roots[i];
076: if (packageFragmentRoot instanceof PackageFragmentRoot &&
077: packageFragmentRoot instanceof JarPackageFragmentRoot == false) {
078:
079: PackageFragmentRoot packRoot = (PackageFragmentRoot)packageFragmentRoot;
080: String newPackagePath = "/" + newPackagename.replace('.', '/');
081: IPath absNewPackagePath = packRoot.getPath().append(newPackagePath); // - internal to the workbench: "/Project/src"
082: IPackageFragment packFrag = javaProject.findPackageFragment(absNewPackagePath);
083:
084: if (packFrag == null) {
085: // create a package for the new package path
086: // and move to the new package
087: IPackageFragment newPackage = packRoot.createPackageFragment(newPackagename, true, null);
088: unit.move(newPackage, null, null, true, null);
089:
090: // delete old empty packages
091: deletePackage(oldPackagename, packRoot, javaProject);
092: }
093: else {
094: // move compilation unit to existing package path
095: unit.move(packFrag, null, null, true, null);
096:
097: // delete old empty packages
098: deletePackage(oldPackagename, packRoot, javaProject);
099: }
100: }
101: }
102: } catch (JavaModelException e) {
103: String message = e.getMessage();
104: ILog logger = LoggingPlugin.getDefault().getLog();
105: String symName = LoggingPlugin.getDefault().getBundle().getSymbolicName();
106: logger.log(new Status(IStatus.ERROR,symName,0,message,e));
107: throw new RuntimeException(e);
108: }
109: }
110: */
111: }
112:
113: /**
114: * Renames the given CompilationUnit.
115: *
116: * @param modelElement the Compilation Unit to rename
117: */
118: private void renameCompilationUnit(IJavaElement modelElement) {
119: String classFileName = Util.classFileName(info
120: .getNewImplementation());
121: try {
122: ((ICompilationUnit) modelElement).rename(classFileName,
123: true, null);
124: } catch (JavaModelException e) {
125: String message = e.getMessage();
126: ILog logger = LoggingPlugin.getDefault().getLog();
127: String symName = LoggingPlugin.getDefault().getBundle()
128: .getSymbolicName();
129: logger
130: .log(new Status(IStatus.ERROR, symName, 0, message,
131: e));
132: throw new RuntimeException(e);
133: }
134: }
135:
136: /**
137: * Deletes the the package with the given name,
138: * in the given fragment root.
139: *
140: * @param name the name of the package
141: * @param root the root containing the package
142: * @param javaProject the java project containing the package
143: */
144: private void deletePackage(String name, PackageFragmentRoot root,
145: IJavaProject javaProject) {
146: try {
147: String oldPackagePath = "/" + name.replace('.', '/');
148: IPath absOldPackagePath = root.getPath().append(
149: oldPackagePath); // - internal to the workbench: "/Project/src"
150: IPackageFragment packageFrag = javaProject
151: .findPackageFragment(absOldPackagePath);
152: IJavaElement[] childs = packageFrag.getChildren();
153: if (childs.length == 0) {
154: packageFrag.delete(true, null);
155: }
156: } catch (JavaModelException e) {
157: String message = e.getMessage();
158: ILog logger = LoggingPlugin.getDefault().getLog();
159: String symName = LoggingPlugin.getDefault().getBundle()
160: .getSymbolicName();
161: logger
162: .log(new Status(IStatus.ERROR, symName, 0, message,
163: e));
164: throw new RuntimeException(e);
165: }
166: }
167:
168: /**
169: * Udates the AST of the given compilation unit and checks
170: * other compilatin units.
171: *
172: * @param modelElement the compilation unit to modify
173: * @see refactor.core.IRefactoring#updateSource(org.eclipse.jdt.core.IJavaElement)
174: */
175: public void updateSource(IJavaElement modelElement) {
176: // TODO if we try to update all referenced classes
177: // we get an endless loop. This should be fixed.
178:
179: /*
180: TypeVisitor typeVisitor = new TypeVisitor();
181: CompilationUnit u = null;
182:
183: List<ICompilationUnit> units = Util.getICompilationUnits();
184: for (Iterator<ICompilationUnit> iterator = units.iterator(); iterator.hasNext();) {
185: u = parse((ICompilationUnit) iterator.next());
186: typeVisitor.process(u,info);
187: ManipulateHelper.saveDirectlyModifiedUnit(u);
188: }
189: */
190: }
191:
192: @Override
193: public void process(RefactorInfo info) {
194: }
195:
196: /* Start the refactoring process.
197: *
198: * @param info the info object
199: */
200: public void process(ModelInfo info) {
201: this .info = info;
202:
203: // search the compilation unit
204: ICompilationUnit unit = getCompilationUnit();
205: if (unit == null) {
206: String message = "No corresponding source file found";
207: ILog logger = LoggingPlugin.getDefault().getLog();
208: String symName = LoggingPlugin.getDefault().getBundle()
209: .getSymbolicName();
210: logger.log(new Status(IStatus.ERROR, symName, 0, message,
211: null));
212: throw new RuntimeException(message);
213: }
214:
215: // rename the compilation unit
216: modification(unit);
217:
218: // updates referenced types
219: updateSource(unit);
220: }
221:
222: /**
223: * Helper method to get the
224: * Compilation Unit for the given implementation.
225: *
226: * @return unit the Compilation Unit found for the implementation value
227: */
228: private ICompilationUnit getCompilationUnit() {
229: String modelImplementation = info.getOldImplementation();
230: List<ICompilationUnit> units = Util.getICompilationUnits();
231: for (Iterator<ICompilationUnit> iterator = units.iterator(); iterator
232: .hasNext();) {
233: ICompilationUnit unit = (ICompilationUnit) iterator.next();
234: String sourceImplementation = Util.getImplementation(unit);
235: if (sourceImplementation.equals(modelImplementation))
236: return unit;
237: }
238: return null;
239: }
240: }
|