package pyUML.refactoring; import java.io.IOException; import java.net.URLDecoder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.MessageDialog; import org.python.copiedfromeclipsesrc.JDTNotAvailableException; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.MisconfigurationException; import org.python.pydev.core.PythonNatureWithoutProjectException; import org.python.pydev.core.REF; import org.python.pydev.editor.codecompletion.shell.AbstractShell; import org.python.pydev.editor.refactoring.AbstractPyRefactoring; import org.python.pydev.editor.refactoring.IPyRefactoring; import org.python.pydev.plugin.nature.PythonNature; import pyUML.exceptions.PyUMLSynchronizeCodeException; import pyUML.pythonTree.PythonTreeFile; /** * Helper class to use the Python pyUML.refactoring functionality * provided by "Bicycle Repair Man", written in Python * as used by PyDev */ public class BicycleRefactoring { /** * This is the generic refactor command using bicycle pyUML.refactoring. * Is is used by specializes pyUML.refactoring methods * * @param refactorCommand - the String with the pyUML.refactoring to be done * @param conditionalMethod - the name of the pyUML.refactoring method * @param project - the current project * @return true on success, false on error */ public static boolean doGenericBikeRefactoring(String refactorCommand, String conditionalMethod, IProject project) throws PyUMLSynchronizeCodeException{ IPyRefactoring pyRefactoring = AbstractPyRefactoring.getPyRefactoring(); IPythonNature pythonNature = PythonNature.getPythonNature(project); try { if ((Boolean) REF.invoke(pyRefactoring, conditionalMethod, new Object[0])) { AbstractShell pytonShell = AbstractShell.getServerShell(pythonNature, AbstractShell.OTHERS_SHELL); String output = ""; try{ pytonShell.changePythonPath(pythonNature.getPythonPathNature().getCompleteProjectPythonPath(null, null)); //default pytonShell.write(refactorCommand); output = URLDecoder.decode(pytonShell.read((IProgressMonitor)null), "UTF-8"); } catch (Exception e) { output = "ERROR: "+e.getClass().getName()+"\n"; e.printStackTrace(); pytonShell.restartShell(); } if (output.startsWith("ERROR:")) { String errmsg = output.substring(0, output.indexOf('\n')); pytonShell.restartShell(); MessageDialog.openError(null, "Error on pyUML.refactoring using Bike!" , "There was a pyUML.refactoring error using the Bicycle Repair Man Browser\n" + "The command was: "+refactorCommand +"\nThe error was: "+errmsg); return false; } } else { throw new PyUMLSynchronizeCodeException("Error on pyUML.refactoring using Bike!\n\n" + "pyRefactoring is not available!"); } }catch (CoreException e) { throw new PyUMLSynchronizeCodeException("CoreException on pyUML.refactoring using Bike!\n\n" + e.getMessage()); }catch (IOException e) { throw new PyUMLSynchronizeCodeException("IOException on pyUML.refactoring using Bike!\n\n" + e.getMessage()); } catch (JDTNotAvailableException e) { throw new PyUMLSynchronizeCodeException("JDTNotAvailableException on pyUML.refactoring using Bike!\n\n" + e.getMessage()); } catch (MisconfigurationException e) { throw new PyUMLSynchronizeCodeException("PyUMLSynchronizeCodeException on pyUML.refactoring using Bike!\n\n" + e.getMessage()); } catch (PythonNatureWithoutProjectException e) { throw new PyUMLSynchronizeCodeException("PythonNatureWithoutProjectException on pyUML.refactoring using Bike!\n\n" + e.getMessage()); } return true; } /** * DO a 'rename' Refactoring. This is for class / method renaming * * @param filePath the Path of the file to edit * (other files may be affected as well) * (use File.toOSString() to get this Path string) * @param newName the new Name of the object * @param line the line of the object * @param col the column of the object * @param project the current project * @return true on success, false otherwise. */ public static boolean doRenameObject(PythonTreeFile file, String newName, int line, int col, IProject project) throws PyUMLSynchronizeCodeException{ String filePath = file.getFilePath().toOSString(); // make sure the line to change is not the last line in file // -> then bike will fail! if (line == file.getFileContent().split("\n").length ) { // insert line and start again FileRefactoring.appendToFile(file, " "); file.getRoot().setChangedFileLine(filePath+":"+line); return true; } String command = "@@BIKE"; command+= "renameByCoordinates"; command+= "|"+filePath; command+= "|"+line; command+= "|"+(col-1); command+= "|"+newName; command+= "END@@"; String conditionalMethod = "canRename"; boolean success = doGenericBikeRefactoring(command, conditionalMethod, project); file.updateFileInEclipse(); return success; } }