RenameImplementation.java :  » Workflow-Engines » osbl-1_0 » core » Java Open Source

Java Open Source » Workflow Engines » osbl 1_0 
osbl 1_0 » core » RenameImplementation.java
/**
 * 
 */
package core;

import java.util.Iterator;
import java.util.List;

import logging.LoggingPlugin;

import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;

/**
 * This class is used by a implementation refactoring. It adapts the 
 * source code to the change of the model implementation property.
 * If the class name of the implementation should be changed this
 * method renames the concerning compilation unit. If the packages
 * of the implementation are different, packages will be created
 * if necessary and the compilation unit will be moved.   
 * @author sh
 *
 */
public class RenameImplementation extends AbstractAST
  implements ICodeRefactoring {
  
  // the Info Object containing all necessary model info
  private ModelInfo info = null;
    
  /** 
   * Renames the given compilation unit.
   * It automatically renames the class file name 
   * and also the type name.
   * 
   * @param modelElement the compilatin unit to rename
   * @see refactor.core.IRefactoring#modification(org.eclipse.jdt.core.IJavaElement)
   */
  @SuppressWarnings({ "restriction" })
  public void modification(IJavaElement modelElement) {  
    // check if a Compilation Unit should be modified
    if (modelElement instanceof ICompilationUnit == false) return;
    
    // get the packages of the info object
    String newPackagename = Util.packagename(info.getNewImplementation());
    String oldPackagename = Util.packagename(info.getOldImplementation());
    
    // check if the type should stay in the same package
    // if the packages are the same, just perfom a renaming
    if (newPackagename.equals(oldPackagename)) {
      renameCompilationUnit(modelElement);
    }
      
    // if the packages are different
    // check if the new package already exist. If so just move the cu
    // otherwise if the new package doesn't exist, create it.
    /*
    else {
      try {
        ICompilationUnit unit = (ICompilationUnit)modelElement;
        IProject project = unit.getCorrespondingResource().getProject();                                  
        IJavaProject javaProject = JavaCore.create(project);
        
        IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
        for (int i = 0; i < roots.length; i++) {
          IPackageFragmentRoot packageFragmentRoot = roots[i];
          if (packageFragmentRoot instanceof PackageFragmentRoot &&
            packageFragmentRoot instanceof JarPackageFragmentRoot == false) {
            
            PackageFragmentRoot packRoot = (PackageFragmentRoot)packageFragmentRoot;
            String newPackagePath = "/" + newPackagename.replace('.', '/');
            IPath absNewPackagePath = packRoot.getPath().append(newPackagePath); // - internal to the workbench: "/Project/src"
            IPackageFragment packFrag = javaProject.findPackageFragment(absNewPackagePath);
            
            if (packFrag == null) {
              // create a package for the new package path
              // and move to the new package
              IPackageFragment newPackage = packRoot.createPackageFragment(newPackagename, true, null);
              unit.move(newPackage, null, null, true, null);
              
              // delete old empty packages
              deletePackage(oldPackagename, packRoot, javaProject);
            }
            else {
              // move compilation unit to existing package path
              unit.move(packFrag, null, null, true, null);
              
              // delete old empty packages
              deletePackage(oldPackagename, packRoot, javaProject);
            }
          }
        } 
      } catch (JavaModelException e) {
        String message = e.getMessage(); 
        ILog logger = LoggingPlugin.getDefault().getLog();
        String symName = LoggingPlugin.getDefault().getBundle().getSymbolicName();
        logger.log(new Status(IStatus.ERROR,symName,0,message,e));
        throw new RuntimeException(e);
      }  
    }
    */
  }
  
  /**
   * Renames the given CompilationUnit.
   * 
   * @param modelElement the Compilation Unit to rename
   */
  private void renameCompilationUnit(IJavaElement modelElement) {
    String classFileName = Util.classFileName(info.getNewImplementation());
    try {
      ((ICompilationUnit)modelElement).rename(classFileName, true, null);
    } 
    catch (JavaModelException e) {
      String message = e.getMessage(); 
      ILog logger = LoggingPlugin.getDefault().getLog();
      String symName = LoggingPlugin.getDefault().getBundle().getSymbolicName();
      logger.log(new Status(IStatus.ERROR,symName,0,message,e));
      throw new RuntimeException(e);
    }   
  }
  
  /**
   * Deletes the the package with the given name,
   * in the given fragment root.
   * 
   * @param name the name of the package
   * @param root the root containing the package
   * @param javaProject the java project containing the package
   */
  private void deletePackage(String name, PackageFragmentRoot root, IJavaProject javaProject) {
    try {
      String oldPackagePath = "/" + name.replace('.', '/');
      IPath absOldPackagePath = root.getPath().append(oldPackagePath); // - internal to the workbench: "/Project/src"
      IPackageFragment packageFrag = javaProject.findPackageFragment(absOldPackagePath);
      IJavaElement[] childs = packageFrag.getChildren();
      if (childs.length == 0) {
        packageFrag.delete(true, null);
      }
    } 
    catch (JavaModelException e) {
      String message = e.getMessage(); 
      ILog logger = LoggingPlugin.getDefault().getLog();
      String symName = LoggingPlugin.getDefault().getBundle().getSymbolicName();
      logger.log(new Status(IStatus.ERROR,symName,0,message,e));
      throw new RuntimeException(e);
    }
  }
  
  /**
   * Udates the AST of the given compilation unit and checks
   * other compilatin units.
   * 
   * @param modelElement the compilation unit to modify
   * @see refactor.core.IRefactoring#updateSource(org.eclipse.jdt.core.IJavaElement)
   */
  public void updateSource(IJavaElement modelElement) {
    // TODO if we try to update all referenced classes
    // we get an endless loop. This should be fixed.
    
    /*
    TypeVisitor typeVisitor = new TypeVisitor();
    CompilationUnit u = null;
        
    List<ICompilationUnit> units = Util.getICompilationUnits();
    for (Iterator<ICompilationUnit> iterator = units.iterator(); iterator.hasNext();) {
      u = parse((ICompilationUnit) iterator.next());    
      typeVisitor.process(u,info);
      ManipulateHelper.saveDirectlyModifiedUnit(u);
    }
    */
  }
  
  @Override
  public void process(RefactorInfo info) {
  }
  
  /* Start the refactoring process.
   * 
   * @param info the info object
   */
  public void process(ModelInfo info) {
    this.info = info;
    
    // search the compilation unit
    ICompilationUnit unit = getCompilationUnit();
    if (unit == null) {
      String message = "No corresponding source file found"; 
      ILog logger = LoggingPlugin.getDefault().getLog();
      String symName = LoggingPlugin.getDefault().getBundle().getSymbolicName();
      logger.log(new Status(IStatus.ERROR,symName,0,message,null));
      throw new RuntimeException(message);
    }
    
    // rename the compilation unit
    modification(unit);
    
    // updates referenced types
    updateSource(unit);
  }

  
  /**
   * Helper method to get the 
   * Compilation Unit for the given implementation.
   * 
   * @return unit the Compilation Unit found for the implementation value 
   */
  private ICompilationUnit getCompilationUnit() {  
    String modelImplementation = info.getOldImplementation();
    List<ICompilationUnit> units = Util.getICompilationUnits();
    for (Iterator<ICompilationUnit> iterator = units.iterator(); iterator.hasNext();) {
      ICompilationUnit unit = (ICompilationUnit) iterator.next();
      String sourceImplementation = Util.getImplementation(unit);      
      if (sourceImplementation.equals(modelImplementation)) 
        return unit;
    }  
    return null;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.