package org.rubypeople.rdt.ui.actions; import java.util.Map; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.ITextFileBufferManager; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.ui.PlatformUI; import org.rubypeople.rdt.core.IRubyScript; import org.rubypeople.rdt.core.RubyModelException; import org.rubypeople.rdt.core.formatter.Indents; import org.rubypeople.rdt.internal.corext.util.RubyModelUtil; import org.rubypeople.rdt.internal.ui.IRubyHelpContextIds; import org.rubypeople.rdt.internal.ui.RubyPlugin; import org.rubypeople.rdt.internal.ui.actions.ActionMessages; import org.rubypeople.rdt.internal.ui.actions.SelectionConverter; import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor; import org.rubypeople.rdt.internal.ui.util.ExceptionHandler; public class SurroundWithBeginRescueAction extends SelectionDispatchAction { public static final String SURROUND_WTH_BEGIN_RESCUE = "SurroundWithBeginRescue"; //$NON-NLS-1$ private RubyEditor fEditor; /** * Note: This constructor is for internal use only. Clients should not call * this constructor. * * @param editor * the compilation unit editor */ public SurroundWithBeginRescueAction(RubyEditor editor) { super(editor.getEditorSite()); setText(ActionMessages.SurroundWithBeginRescueAction_label); fEditor = editor; setEnabled((fEditor != null && SelectionConverter.getInputAsRubyScript(fEditor) != null)); PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IRubyHelpContextIds.SURROUND_WITH_TRY_CATCH_ACTION); } public void run(ITextSelection selection) { try { createChange(selection, new NullProgressMonitor()); } catch (CoreException e) { ExceptionHandler.handle(e, getDialogTitle(), ActionMessages.SurroundWithBeginRescueAction_error); } } private static String getDialogTitle() { return ActionMessages.SurroundWithBeginRescueAction_dialog_title; } private IFile getFile() { IRubyScript cu = getRubyScript(); return (IFile) RubyModelUtil.toOriginal(cu).getResource(); } private IRubyScript getRubyScript() { return SelectionConverter.getInputAsRubyScript(fEditor); } /* * non Java-doc * * @see IRefactoring#createChange(IProgressMonitor) */ public void createChange(ITextSelection selection, IProgressMonitor pm) throws CoreException { final String NN = ""; //$NON-NLS-1$ if (pm == null) pm = new NullProgressMonitor(); pm.beginTask(NN, 2); // This is cheap since the compilation unit is already open in a editor. IPath path = getFile().getFullPath(); ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); try { bufferManager.connect(path, new SubProgressMonitor(pm, 1)); IDocument document = bufferManager.getTextFileBuffer(path).getDocument(); String text = createBeginRescueBlock(document, selection); document.replace(selection.getOffset(), selection.getLength(), text); } catch (BadLocationException e) { throw new CoreException(new Status(IStatus.ERROR, RubyPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e)); } finally { bufferManager.disconnect(path, new SubProgressMonitor(pm, 1)); pm.done(); } } private String createBeginRescueBlock(IDocument document, ITextSelection selection) throws BadLocationException, RubyModelException { String originalText = selection.getText(); String lineDelimiter = document.getLineDelimiter(0); Map options = getRubyScript().getRubyProject().getOptions(true); int lineNumber = selection.getStartLine(); String line = document.get(document.getLineOffset(lineNumber), document .getLineLength(lineNumber)); int indentationUnits = Indents.measureIndentUnits(line, Indents.getTabWidth(options), Indents.getIndentWidth(options)); StringBuffer text = new StringBuffer(); text.append("begin");//$NON-NLS-1$ text.append(lineDelimiter); text.append(Indents.createIndentString(indentationUnits + 1, options)); text.append(originalText); text.append(lineDelimiter); text.append(Indents.createIndentString(indentationUnits, options)); text.append("rescue StandardError => e");//$NON-NLS-1$ text.append(lineDelimiter); text.append(Indents.createIndentString(indentationUnits + 1, options)); text.append("puts e");//$NON-NLS-1$ text.append(lineDelimiter); text.append(Indents.createIndentString(indentationUnits, options)); text.append("end");//$NON-NLS-1$ text.append(lineDelimiter); text.append(Indents.createIndentString(indentationUnits, options)); return text.toString(); } public void selectionChanged(ITextSelection selection) { setEnabled(selection.getLength() > 0 && (fEditor != null && SelectionConverter.getInputAsRubyScript(fEditor) != null)); } }