/******************************************************************************* * Copyright (c) 2005, 2006 Eclipse Foundation * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bjorn Freeman-Benson - initial implementation * Ward Cunningham - initial implementation *******************************************************************************/ package org.eclipse.eclipsemonkey.actions; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.eclipsemonkey.EclipseMonkeyPlugin; import org.eclipse.eclipsemonkey.ScriptMetadata; import org.eclipse.eclipsemonkey.language.IMonkeyLanguageFactory; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.RTFTransfer; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; import org.eclipse.ui.PartInitException; import org.eclipse.ui.views.navigator.ResourceNavigator; /** * PasteScriptFromClipboardAction */ public class PasteScriptFromClipboardAction implements IWorkbenchWindowActionDelegate, IObjectActionDelegate { private static final String ECLIPSE_MONKEY_PROJECT = Messages.PasteScriptFromClipboardAction_Monkey_project_name; private static final String ECLIPSE_MONKEY_DIRECTORY = "scripts"; //$NON-NLS-1$ /** * */ public PasteScriptFromClipboardAction() { } /** * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */ public void run(IAction action) { TextAndRTF text = getTextFromClipboard(); Collection scripts = extractScriptsFromText(text); for (Iterator iter = scripts.iterator(); iter.hasNext();) { try { String scriptText = (String) iter.next(); scriptText = collapseEscapedNewlines(scriptText); IFolder destination = findDestinationFor(scriptText); IFile file = createScriptFile(destination, scriptText); highlightNewScriptInNavigator(file); } catch (CoreException x) { MessageDialog.openInformation(shell, Messages.PasteScriptFromClipboardAction_INF_TTL_Unable_create_examples_project, Messages.PasteScriptFromClipboardAction_INF_MSG_Unable_create_examples_project + x); } catch (IOException x) { MessageDialog.openInformation(shell, Messages.PasteScriptFromClipboardAction_INF_TTL_Unable_create_examples_project, Messages.PasteScriptFromClipboardAction_INF_MSG_Unable_create_examples_project + x); } } if (scripts.isEmpty()) { MessageDialog .openInformation( shell, Messages.PasteScriptFromClipboardAction_INF_TTL_Cant_find_script_on_clipboard, Messages.PasteScriptFromClipboardAction_INF_MSG_Cant_find_script_on_clipboard); } } String collapseEscapedNewlines(String input) { Pattern pattern = Pattern.compile("\\\\(\n|(\r\n?))"); //$NON-NLS-1$ Matcher match = pattern.matcher(input); String result = match.replaceAll(""); //$NON-NLS-1$ return result; } private void highlightNewScriptInNavigator(IFile file) throws PartInitException { if (window != null) { window.getActivePage().showView( "org.eclipse.ui.views.ResourceNavigator"); //$NON-NLS-1$ IViewReference[] refs = window.getActivePage().getViewReferences(); for (int i = 0; i < refs.length; i++) { IViewReference reference = refs[i]; if (reference.getId().equals( "org.eclipse.ui.views.ResourceNavigator")) { //$NON-NLS-1$ ResourceNavigator nav = (ResourceNavigator) reference .getView(true); IStructuredSelection sel = new StructuredSelection(file); nav.selectReveal(sel); } } } } private IFolder findDestinationFor(String script) throws CoreException { if (selection != null && selection.getFirstElement() instanceof IFolder) { IFolder element = (IFolder) selection.getFirstElement(); if ((element).getName().equals(ECLIPSE_MONKEY_DIRECTORY)) { return element; } } IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject[] projects = workspace.getRoot().getProjects(); IProject project = null; for (int i = 0; i < projects.length; i++) { IProject p = projects[i]; if (p.getName().equals(ECLIPSE_MONKEY_PROJECT)) { project = p; break; } } if (project == null) { project = workspace.getRoot().getProject(ECLIPSE_MONKEY_PROJECT); project.create(null); project.open(null); } IFolder folder = project.getFolder(ECLIPSE_MONKEY_DIRECTORY); if (!folder.exists()) folder.create(IResource.NONE, true, null); return folder; } private IFile createScriptFile(IFolder destination, String script) throws CoreException, IOException { // FIXME This just assumes that the script must be JavaScript! IMonkeyLanguageFactory langFactory = (IMonkeyLanguageFactory) EclipseMonkeyPlugin.getDefault().getLanguageStore().get("js"); //$NON-NLS-1$ ScriptMetadata metadata = langFactory.getScriptMetadata(script); String basename = metadata.getReasonableFilename(); int ix = basename.lastIndexOf("."); //$NON-NLS-1$ if (ix > 0) { basename = basename.substring(0, ix); } IResource[] members = destination.members(0); Pattern suffix = Pattern.compile(basename + "(-(\\d+))?\\.js"); //$NON-NLS-1$ int maxsuffix = -1; for (int i = 0; i < members.length; i++) { IResource resource = members[i]; if (resource instanceof IFile) { IFile file = (IFile) resource; String filename = file.getName(); Matcher match = suffix.matcher(filename); if (match.matches()) { if (match.group(2) == null) { maxsuffix = Math.max(maxsuffix, 0); } else { int n = Integer.parseInt(match.group(2)); maxsuffix = Math.max(maxsuffix, n); } } } } String filename = (maxsuffix == -1) ? filename = basename + ".js" //$NON-NLS-1$ : basename + "-" + (maxsuffix + 1) + ".js"; //$NON-NLS-1$ //$NON-NLS-2$ ByteArrayInputStream stream = new ByteArrayInputStream(script .getBytes()); IFile file = destination.getFile(filename); file.create(stream, false, null); stream.close(); return file; } private TextAndRTF getTextFromClipboard() { TextAndRTF result = new TextAndRTF(); Clipboard clipboard = new Clipboard(shell.getDisplay()); try { TextTransfer textTransfer = TextTransfer.getInstance(); RTFTransfer rtfTransfer = RTFTransfer.getInstance(); result.text = (String) clipboard.getContents(textTransfer); result.rtf = (String) clipboard.getContents(rtfTransfer); return result; } finally { clipboard.dispose(); } } private Collection extractScriptsFromText(TextAndRTF text) { Collection result = new ArrayList(); Pattern pattern = Pattern.compile( EclipseMonkeyPlugin.PUBLISH_BEFORE_MARKER + "\\s*(.*?)\\s*" //$NON-NLS-1$ + EclipseMonkeyPlugin.PUBLISH_AFTER_MARKER, Pattern.DOTALL); Pattern crpattern = Pattern.compile("\r\n?"); //$NON-NLS-1$ if (text.text != null) { Matcher matcher = pattern.matcher(text.text); while (matcher.find()) { String string = matcher.group(1); Matcher crmatch = crpattern.matcher(string); string = crmatch.replaceAll("\n"); //$NON-NLS-1$ if (string.indexOf("\n") >= 0) { //$NON-NLS-1$ result.add(string); } } } if (result.isEmpty() && text.rtf != null) { Matcher matcher = pattern.matcher(text.rtf); Pattern escapesPattern = Pattern.compile("\\\\(.)"); //$NON-NLS-1$ while (matcher.find()) { String string = matcher.group(1); string = string.replaceAll("\\\\line", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ Matcher escapes = escapesPattern.matcher(string); string = escapes.replaceAll("$1"); //$NON-NLS-1$ Matcher crmatch = crpattern.matcher(string); string = crmatch.replaceAll("\n"); //$NON-NLS-1$ if (string.indexOf("\n") >= 0) { //$NON-NLS-1$ result.add(string); } } } return result; } private IStructuredSelection selection = null; /** * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) */ public void selectionChanged(IAction action, ISelection selection) { this.selection = (IStructuredSelection) selection; } /** * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() */ public void dispose() { } /** * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) */ public void init(IWorkbenchWindow window) { this.shell = window.getShell(); this.window = window; } private Shell shell; private IWorkbenchWindow window; /** * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart) */ public void setActivePart(IAction action, IWorkbenchPart targetPart) { this.shell = targetPart.getSite().getShell(); this.window = null; } class TextAndRTF { String text; String rtf; } }