/******************************************************************* * Copyright (c) 2006-2008, Cloudsmith Inc. * The code, documentation and other materials contained herein * are the sole and exclusive property of Cloudsmith Inc. and may * not be disclosed, used, modified, copied or distributed without * prior written consent or license from Cloudsmith Inc. ******************************************************************/ package org.eclipse.buckminster.rssowl.ui; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import org.eclipse.buckminster.download.DownloadManager; import org.eclipse.buckminster.jnlp.ide.IDEApplication; import org.eclipse.buckminster.runtime.IOUtils; import org.eclipse.buckminster.ui.editor.ExternalFileEditorInput; import org.eclipse.buckminster.ui.UiPlugin; import org.eclipse.buckminster.ui.UiUtils; import org.eclipse.buckminster.ui.actions.BlankQueryAction; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.browser.IWebBrowser; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.rssowl.ui.spi.IRewriteResult; import org.rssowl.ui.spi.IRewriter; import org.rssowl.ui.spi.Result; /** * Rewrites URLs for buckminster: scheme, and buckminster artifacts on display in the RSS OWL browser. * Runs materializer, or opens cquery editor. * * @author Henrik Lindberg * */ public class BuckminsterURIRewriter implements IRewriter { private static final IRewriteResult s_continue = new Result(false); public IRewriteResult rewrite(final String location) { if(location == null || location.length() < 1) return s_continue; URI uri = null; try { uri = new URI(location); } catch(URISyntaxException e) { return s_continue; // let someone else worry about the malformed URI } cloudsmithRules: { if(uri.getHost() == null || !uri.getHost().contains("cloudsmith.com")) //$NON-NLS-1$ break cloudsmithRules; String path = uri.getRawPath(); if(path == null || path.length() < 1) break cloudsmithRules; rule: // add eclipse=1 URL parameter { // This rule adds an "eclipse=1" parameter to an URL that points to cloudsmith materialization page // to allow it to render the materialization using the buckminster: scheme // if(!path.contains("dynamic/view") || !path.contains("component")) //$NON-NLS-1$ //$NON-NLS-2$ break rule; if(location.contains("eclipse=1")) break rule; // already appended "eclipse=1" StringBuilder bld = new StringBuilder(location.length() + 10); bld.append(location); // if there was a query string already, the added parameter must have & separator bld.append(uri.getRawQuery() == null ? "?" //$NON-NLS-1$ : "&"); //$NON-NLS-1$ bld.append("eclipse=1"); //$NON-NLS-1$ return new Result(bld.toString()); } } rule: { if(uri.getScheme() == null || !uri.getScheme().equals("buckminster")) //$NON-NLS-1$ break rule; // parse the buckminster scheme specific part into Action and parameters // String schemeSpecificPart = uri.getRawSchemeSpecificPart(); try { URI schemeURI = new URI(schemeSpecificPart); String actionName = schemeURI.getScheme(); String actionData = schemeURI.getRawSchemeSpecificPart(); // buckminster:materialize:URL if("materialize".equals(actionName)) //$NON-NLS-1$ { // what follows the materialize scheme should be a jnlp URI // URI jnlpURI = new URI(actionData); return new Result(new MaterializeAction(jnlpURI), true); } } catch(URISyntaxException e) { e.printStackTrace(); return s_continue; } } rule: { if(uri.getPath() == null || !uri.getPath().endsWith(".cquery")) //$NON-NLS-1$ break rule; return new Result(new OpenCQueryAction(uri), true); } return s_continue; } private static class MaterializeAction extends Action { private final URI m_jnlpURI; /** * Runs materialization inside the IDE (or the external materializer). The input should be a URI to a * materializer .jnlp. The Execution is asynchronous on the UI thread as we are deep in processing of an event * from the internal browser. * * @param m_jnlpURI */ public MaterializeAction(URI jnlpURI) { m_jnlpURI = jnlpURI; } @Override public void run() { // Cloudsmith rearranges not only the last part of the jnlp to get the properties // but also the URL itself - we could parse the .jnlp, but the transformation on the // URL itself is known. // All non cloudsmith URL's just gets the last "jnlp" modified to a "prop" String urlString = null; String host = m_jnlpURI.getHost(); if(host != null && host.contains("cloudsmith.com")) //$NON-NLS-1$ { // a cloudsmith .jnlp String scheme = m_jnlpURI.getScheme(); int port = m_jnlpURI.getPort(); String userInfo = m_jnlpURI.getRawUserInfo(); String path = m_jnlpURI.getPath(); String query = m_jnlpURI.getRawQuery(); String fragment = m_jnlpURI.getRawFragment(); // transform the path // from: /dynamic/jnlp/materialize/xxxx-nnnn.jnlp // to: /dynamic/prop/jnlp/xxxx-nnnn.prop // String[] segments = path.split("/"); //$NON-NLS-1$ segments[2] = "prop"; //$NON-NLS-1$ segments[3] = "jnlp"; //$NON-NLS-1$ segments[4] = segments[4].replace(".jnlp", ".prop"); //$NON-NLS-1$ // put new URI together // - concatenate the path // - construct new URI // StringBuilder bld = new StringBuilder(); // append them - initial segment is an empty "" so skip it for(int i = 1; i < segments.length; i++) { bld.append("/"); //$NON-NLS-1$ bld.append(segments[i]); } path = bld.toString(); URI propURI = null; try { propURI = new URI(scheme, userInfo, host, port, path, query, fragment); } catch(URISyntaxException e) { e.printStackTrace(); MessageDialog.openError(null, "Internal Problem", "Could not create resulting URI from: " + m_jnlpURI.toString()); return; } urlString = propURI.toString(); } else { // non cloudsmith .jnlp urlString = m_jnlpURI.toString().replace(".jnlp", ".prop"); //$NON-NLS-1$ //$NON-NLS-2$ } // Ask if user wants to run this in the IDE or in the browser. IPreferenceStore prefsStore = UiPlugin.getDefault().getPreferenceStore(); String prefsKey = "buckminster.materializer.jnlp.materializeInExternalBrowser"; //$NON-NLS-1$ MessageDialogWithToggle m = MessageDialogWithToggle.openOkCancelConfirm(null, "Start Materialization Wizard", "Do you want to run the materialization wizard now?", "Run in external browser", prefsStore.getBoolean(prefsKey), null, prefsKey); prefsStore.setValue(prefsKey, m.getToggleState()); if(prefsStore.needsSaving()) UiPlugin.getDefault().savePluginPreferences(); if(m.getReturnCode() == MessageDialogWithToggle.CANCEL) return; if(m.getToggleState()) { // in external browser IWebBrowser browser; try { browser = org.eclipse.buckminster.generic.ui.utils.UiUtils.getWorkbench().getBrowserSupport() .createBrowser(IWorkbenchBrowserSupport.AS_EXTERNAL, null, "Materialization", ""); browser.openURL(new URL(m_jnlpURI.toString())); } catch(PartInitException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch(MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { final IDEApplication ideapp = new IDEApplication(); try { ideapp.start(urlString); } catch(Exception e) { ideapp.setState(IDEApplication.State.FAILED); } } } } /** * Opens the CQUery editor for a cquery URI/URL * @author Henrik Lindberg * */ public static class OpenCQueryAction extends Action { final private URI m_cqueryURI; public OpenCQueryAction(URI cqueryURI) { m_cqueryURI = cqueryURI; } @Override public void run() { String urlStr = m_cqueryURI.toString(); IWorkbench workbench = PlatformUI.getWorkbench(); try { URL url = new URL(urlStr); File tempFile = File.createTempFile(BlankQueryAction.TEMP_FILE_PREFIX, ".cquery"); tempFile.deleteOnExit(); IEditorDescriptor ed = workbench.getEditorRegistry().getDefaultEditor("buckminster.cquery"); //$NON-NLS-1$ OutputStream output = null; try { output = new FileOutputStream(tempFile); DownloadManager.readInto(url, null, output, null); } finally { IOUtils.close(output); } workbench.getActiveWorkbenchWindow().getActivePage().openEditor( new ExternalFileEditorInput(tempFile, new Path(m_cqueryURI.getPath()).lastSegment(), urlStr), ed.getId()); } catch(Exception e) { UiUtils.openError(workbench.getActiveWorkbenchWindow().getShell(), "Unable to open editor", e); } } } }