/******************************************************************************* * Copyright (c) 2012, 2015 Pivotal Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Pivotal Software, Inc. - initial API and implementation * IBM - Switching to use the more generic AbstractCloudFoundryUrl * instead concrete CloudServerURL, deprecating non-recommended methods ********************************************************************************/ package org.cloudfoundry.ide.eclipse.server.ui.internal; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import org.cloudfoundry.client.lib.CloudCredentials; import org.cloudfoundry.ide.eclipse.server.core.AbstractCloudFoundryUrl; import org.cloudfoundry.ide.eclipse.server.core.internal.CloudErrorUtil; import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryBrandingExtensionPoint; import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryBrandingExtensionPoint.CloudServerURL; import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryPlugin; import org.cloudfoundry.ide.eclipse.server.core.internal.client.CloudFoundryServerBehaviour; import org.cloudfoundry.ide.eclipse.server.core.internal.spaces.CloudOrgsAndSpaces; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.DialogPage; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.browser.IWebBrowser; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.eclipse.ui.internal.browser.WebBrowserPreference; import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport; import org.eclipse.ui.views.IViewDescriptor; import org.eclipse.ui.views.IViewRegistry; import org.springframework.web.client.ResourceAccessException; /** * @author Steffen Pingel * @author Christian Dupuis * @author Terry Denney */ @SuppressWarnings("restriction") public class CloudUiUtil { public static final String SERVERS_VIEW_ID = "org.eclipse.wst.server.ui.ServersView"; //$NON-NLS-1$ public static String ATTR_USER_DEFINED_URLS = "org.cloudfoundry.ide.eclipse.server.user.defined.urls"; //$NON-NLS-1$ public static IStatus runForked(final ICoreRunnable coreRunner, IWizard wizard) { try { IRunnableWithProgress runner = new IRunnableWithProgress() { public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { coreRunner.run(monitor); } catch (Exception e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }; wizard.getContainer().run(true, false, runner); } catch (InvocationTargetException e) { IStatus status; if (e.getCause() instanceof CoreException) { status = new Status(IStatus.ERROR, CloudFoundryServerUiPlugin.PLUGIN_ID, NLS.bind( Messages.CloudUiUtil_ERROR_FORK_OP_FAILED, e.getCause().getMessage()), e); } else { status = new Status(IStatus.ERROR, CloudFoundryServerUiPlugin.PLUGIN_ID, NLS.bind( Messages.CloudUiUtil_ERROR_FORK_UNEXPECTED, e.getMessage()), e); } CloudFoundryServerUiPlugin.getDefault().getLog().log(status); IWizardPage page = wizard.getContainer().getCurrentPage(); if (page instanceof DialogPage) { ((DialogPage) page).setErrorMessage(status.getMessage()); } return status; } catch (InterruptedException e) { return Status.CANCEL_STATUS; } return Status.OK_STATUS; } private static CloudServerURL convertAbstractCloudFoundryUrlToCloudServerURL (AbstractCloudFoundryUrl abstractUrl) { CloudServerURL cloudUrl = null; if (abstractUrl != null) { // Nothing to do, this is already an old CloudServerURL, just return it if (abstractUrl instanceof CloudServerURL) { cloudUrl = (CloudServerURL)(abstractUrl); } else { cloudUrl = new CloudServerURL(abstractUrl.getName(), abstractUrl.getUrl(), abstractUrl.getUserDefined(), abstractUrl.getSignUpUrl(), abstractUrl.getSelfSigned()); } } return cloudUrl; } private static List<CloudServerURL> convertAbstractCloudFoundryUrlListToCloudServerURLList (List <AbstractCloudFoundryUrl> abstractUrls) { if (abstractUrls == null) return null; List<CloudServerURL> urls = new ArrayList<CloudFoundryBrandingExtensionPoint.CloudServerURL>(); for (AbstractCloudFoundryUrl abstractUrl : abstractUrls) { if (abstractUrl != null) { urls.add (convertAbstractCloudFoundryUrlToCloudServerURL(abstractUrl)); } } return urls; } /** * @deprecated use {@link CloudServerUIUtil#getAllUrls(String, IRunnableContext)} */ public static List<CloudServerURL> getAllUrls(String serverTypeId) { try { // Switch to new generic utility method, then convert to the expected return type return convertAbstractCloudFoundryUrlListToCloudServerURLList(CloudServerUIUtil.getAllUrls(serverTypeId, null)); } catch (CoreException ex) { CloudFoundryServerUiPlugin.logError(ex); } // If an exception shows up, return an empty list (to have backwards compatibility) return new ArrayList<CloudServerURL>(); } /** * @deprecated use {@link CloudServerUIUtil#getDefaultUrl(String, IRunnableContext)} */ public static CloudServerURL getDefaultUrl(String serverTypeId) { CloudServerURL url = null; try { // Switch to new generic utility method, then convert to the expected return type AbstractCloudFoundryUrl abstractUrl = CloudServerUIUtil.getDefaultUrl(serverTypeId, null); if (abstractUrl != null) { url = convertAbstractCloudFoundryUrlToCloudServerURL(abstractUrl); } } catch (CoreException ex) { CloudFoundryServerUiPlugin.logError(ex); } return url; } /** * @deprecated use {@link CloudServerUIUtil#getUrls(String, IRunnableContext)} */ public static List<CloudServerURL> getUrls(String serverTypeId) { try { // Switch to new generic utility method, then convert to the expected return type return convertAbstractCloudFoundryUrlListToCloudServerURLList(CloudServerUIUtil.getUrls(serverTypeId, null)); } catch (CoreException ex) { CloudFoundryServerUiPlugin.logError(ex); } // If an exception shows up, return an empty list (to have backwards compatibility) return new ArrayList<CloudServerURL>(); } /** * @deprecated use {@link CloudServerUIUtil#getUserDefinedUrls(String))} */ public static List<CloudServerURL> getUserDefinedUrls(String serverTypeId) { // Switch to new generic utility method, then convert to the expected return type return convertAbstractCloudFoundryUrlListToCloudServerURLList(CloudServerUIUtil.getUserDefinedUrls(serverTypeId)); } /** * @deprecated user {@link CloudServerUIUtil#storeUserDefinedUrls(String, List)} */ public static void storeUserDefinedUrls(String serverTypeId, List<CloudServerURL> urls) { if (urls == null) return; List <AbstractCloudFoundryUrl> abstractUrls = new ArrayList <AbstractCloudFoundryUrl> (); for (CloudServerURL cloudUrl : urls) { abstractUrls.add(cloudUrl); } // Use the new correct method CloudServerUIUtil.storeUserDefinedUrls(serverTypeId, abstractUrls); } /** * Validates the given credentials. Throws {@link CoreException} if error * occurred during validation. * @param userName * @param password * @param urlText * @param displayURL * @param selfSigned true if its a server using self-signed certificate. If * this information is not known, set this to false * @param context * * @throws CoreException if validation failed and error type cannot be * determined * @throws OperationCanceledException if validation is cancelled. */ public static void validateCredentials(final String userName, final String password, final String urlText, final boolean displayURL, final boolean selfSigned, IRunnableContext context) throws CoreException, OperationCanceledException { try { ICoreRunnable coreRunner = new ICoreRunnable() { public void run(IProgressMonitor monitor) throws CoreException { String url = urlText; if (displayURL) { url = getUrlFromDisplayText(urlText); } CloudFoundryServerBehaviour.validate(url, userName, password, selfSigned, monitor); } }; if (context != null) { runForked(coreRunner, context); } else { runForked(coreRunner); } } catch (CoreException ce) { if (ce.getCause() instanceof ResourceAccessException && ce.getCause().getCause() instanceof javax.net.ssl.SSLPeerUnverifiedException) { // Self-signed error. Re-throw as it will involve a client // change throw CloudErrorUtil.toCoreException(ce.getCause().getCause()); } else { throw ce; } } } /** * Runnable context can be null. If so, default Eclipse progress service * will be used as a runnable context. Display URL should be true if the * display URL is passed. If so, and attempt will be made to parse the * actual URL. * * @param userName must not be null * @param password must not be null * @param urlText must not be null. Can be either display or actual URL * @param displayURL true if URL is display URL * @param selfSigned true if connecting to a self-signing server. False otherwise * @param context may be optional * @return spaces descriptor, or null if it couldn't be determined * @throws CoreException */ public static CloudOrgsAndSpaces getCloudSpaces(final String userName, final String password, final String urlText, final boolean displayURL, final boolean selfSigned, IRunnableContext context) throws CoreException { try { final CloudOrgsAndSpaces[] supportsSpaces = new CloudOrgsAndSpaces[1]; ICoreRunnable coreRunner = new ICoreRunnable() { public void run(IProgressMonitor monitor) throws CoreException { String url = urlText; if (displayURL) { url = getUrlFromDisplayText(urlText); } supportsSpaces[0] = CloudFoundryServerBehaviour.getCloudSpacesExternalClient(new CloudCredentials( userName, password), url, selfSigned, monitor); } }; if (context != null) { runForked(coreRunner, context); } else { runForked(coreRunner); } return supportsSpaces[0]; } catch (OperationCanceledException e) { throw new CoreException(CloudFoundryPlugin.getErrorStatus(e)); } } public static String getUrlFromDisplayText(String displayText) { String url = displayText; if (url != null) { int pos = url.lastIndexOf(" - "); //$NON-NLS-1$ if (pos >= 0) { return url.substring(pos + 3); } } return url; } public static String getDisplayTextFromUrl(String url, String serverTypeId) { try { List<AbstractCloudFoundryUrl> cloudUrls = CloudServerUIUtil.getAllUrls(serverTypeId, null); for (AbstractCloudFoundryUrl cloudUrl : cloudUrls) { if (cloudUrl.getUrl().equals(url)) { return cloudUrl.getName() + " - " + url; //$NON-NLS-1$ } } } catch (CoreException ex) { CloudFoundryServerUiPlugin.logError(ex); } return url; } public static void runForked(final ICoreRunnable coreRunner) throws OperationCanceledException, CoreException { runForked(coreRunner, PlatformUI.getWorkbench().getProgressService()); } public static void runForked(final ICoreRunnable coreRunner, IRunnableContext progressService) throws OperationCanceledException, CoreException { try { IRunnableWithProgress runner = new IRunnableWithProgress() { public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ try { coreRunner.run(monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }; progressService.run(true, true, runner); } catch (InvocationTargetException e) { if (e.getCause() instanceof CoreException) { throw (CoreException) e.getCause(); } else { CloudFoundryServerUiPlugin .getDefault() .getLog() .log(new Status(IStatus.ERROR, CloudFoundryServerUiPlugin.PLUGIN_ID, "Unexpected exception", e)); //$NON-NLS-1$ } } catch (InterruptedException e) { throw new OperationCanceledException(); } } public static void openUrl(String location) { openUrl(location, WebBrowserPreference.getBrowserChoice()); } public static void openUrl(String location, int browserChoice) { try { URL url = null; if (location != null) { url = new URL(location); } if (browserChoice == WebBrowserPreference.EXTERNAL) { try { IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport(); support.getExternalBrowser().openURL(url); } catch (Exception e) { } } else { IWebBrowser browser; int flags; if (WorkbenchBrowserSupport.getInstance().isInternalWebBrowserAvailable()) { flags = IWorkbenchBrowserSupport.AS_EDITOR | IWorkbenchBrowserSupport.LOCATION_BAR | IWorkbenchBrowserSupport.NAVIGATION_BAR; } else { flags = IWorkbenchBrowserSupport.AS_EXTERNAL | IWorkbenchBrowserSupport.LOCATION_BAR | IWorkbenchBrowserSupport.NAVIGATION_BAR; } String generatedId = "org.eclipse.mylyn.web.browser-" + Calendar.getInstance().getTimeInMillis(); //$NON-NLS-1$ browser = WorkbenchBrowserSupport.getInstance().createBrowser(flags, generatedId, null, null); browser.openURL(url); } } catch (PartInitException e) { MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.CloudUiUtil_ERROR_OPEN_BROWSER_FAIL_TITLE, Messages.CloudUiUtil_ERROR_OPEN_BROWSER_BODY); } catch (MalformedURLException e) { if (location == null || location.trim().equals("")) { //$NON-NLS-1$ MessageDialog.openInformation(Display.getDefault().getActiveShell(), Messages.CloudUiUtil_ERROR_OPEN_BROWSER_FAIL_TITLE, NLS.bind(Messages.CloudUiUtil_ERROR_EMPTY_URL_BODY, location)); } else { MessageDialog.openInformation(Display.getDefault().getActiveShell(), Messages.CloudUiUtil_ERROR_OPEN_BROWSER_FAIL_TITLE, NLS.bind(Messages.CloudUiUtil_ERROR_MALFORM_URL_BODY, location)); } } } /** * Prompts user to define a value for the wildcard in the cloud URL, then * return the new URL * * @param cloudUrl * @param allCloudUrls * @param shell * @return new URL, null if no wildcard appears in cloudUrl or if user * cancels out of defining a new value * @deprecated use {@link CloudServerUIUtil#getWildcardUrl(AbstractCloudFoundryUrl, List, Shell)} instead. */ public static CloudServerURL getWildcardUrl(CloudServerURL cloudUrl, List<CloudServerURL> allCloudUrls, Shell shell) { // Switch to new generic utility method, then convert to the expected return type ArrayList <AbstractCloudFoundryUrl> allCloudFoundryUrls = new ArrayList<AbstractCloudFoundryUrl>(); if (allCloudUrls != null) { for (CloudServerURL _cloudUrl : allCloudUrls) { allCloudFoundryUrls.add (_cloudUrl); } } AbstractCloudFoundryUrl returnUrl = CloudServerUIUtil.getWildcardUrl(cloudUrl, allCloudFoundryUrls, shell); if (returnUrl != null) { return new CloudServerURL(returnUrl.getName(), returnUrl.getUrl(), true, returnUrl.getSelfSigned()); } return null; } /** * If the Servers view is available and it contains a selection, the * corresponding structured selection is returned. In any other case, * including the Servers view being unavailable, either because it is not * installed or it is closed, null is returned. * @return structured selection in the Servers view, if the Servers view is * open and available, or null otherwise */ public static IStructuredSelection getServersViewSelection() { IViewRegistry registry = PlatformUI.getWorkbench().getViewRegistry(); String serversViewID = SERVERS_VIEW_ID; // fast check to verify that the servers View is available. IViewDescriptor serversViewDescriptor = registry.find(serversViewID); if (serversViewDescriptor != null) { // Granular null checks required as any of the workbench components // may not be available at some given point in time (e.g., during // start/shutdown) IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (activeWorkbenchWindow != null) { IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage(); if (activePage != null) { IViewReference[] references = activePage.getViewReferences(); if (references != null) { IViewPart serversViewPart = null; for (IViewReference reference : references) { if (serversViewID.equals(reference.getId())) { serversViewPart = reference.getView(true); break; } } if (serversViewPart != null) { IViewSite viewSite = serversViewPart.getViewSite(); if (viewSite != null) { ISelectionProvider selectionProvider = viewSite.getSelectionProvider(); if (selectionProvider != null) { ISelection selection = selectionProvider.getSelection(); if (selection instanceof IStructuredSelection) { return (IStructuredSelection) selection; } } } } } } } } return null; } /** * Returns the current shell or null. * @return */ public static Shell getShell() { return PlatformUI.getWorkbench().getModalDialogShellProvider().getShell(); } }