/******************************************************************************* * Copyright (c) 2014 Zend Technologies. * All rights reserved. This program and the accompanying materials * are the copyright of Zend Technologies and is protected under * copyright laws of the United States. * You must not copy, adapt or redistribute this document for * any use. *******************************************************************************/ package org.zend.php.zendserver.deployment.ui; import java.io.IOException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.statushandlers.StatusManager; import org.zend.php.zendserver.deployment.core.targets.EclipseApiKeyDetector; import org.zend.php.zendserver.deployment.core.targets.TargetsManagerService; import org.zend.php.zendserver.deployment.core.targets.ZendServerManager; import org.zend.php.zendserver.deployment.ui.actions.ZendDetectTargetCmdLine; import org.zend.php.zendserver.deployment.ui.zendserver.Messages; import org.zend.sdklib.SdkException; import org.zend.sdklib.internal.target.ApiKeyDetector; import org.zend.sdklib.internal.target.ZendTarget; import org.zend.sdklib.internal.utils.EnvironmentUtils; import org.zend.sdklib.manager.DetectionException; import org.zend.sdklib.manager.PrivilegesException; import org.zend.sdklib.manager.ServerVersionException; import org.zend.sdklib.manager.TargetsManager; import org.zend.sdklib.target.IZendTarget; import org.zend.sdklib.target.InvalidCredentialsException; import org.zend.sdklib.target.LicenseExpiredException; import org.zend.webapi.core.WebApiException; import org.zend.webapi.core.connection.data.values.ServerType; import org.zend.webapi.core.connection.data.values.WebApiVersion; import org.zend.webapi.internal.core.connection.exception.InvalidResponseException; import swt.elevate.ElevatedProgram; import swt.elevate.ElevatedProgramFactory; /** * Class responsible for detection of local Zend Server target. It should be * used as a part of local Zend Server detection process. * * * @author Wojciech Galanciak, 2014 * */ public class LocalTargetDetector { private IZendTarget finalTarget; private IStatus status; public IZendTarget getFinalTarget() { return finalTarget; } public IStatus getStatus() { return status; } public void detect() { try { status = Status.OK_STATUS; TargetsManager manager = TargetsManagerService.INSTANCE .getTargetManager(); try { // TODO handle a case when server has older version - elevate + // default detection finalTarget = detectZendServer6(null); if (finalTarget != null || status.getSeverity() == IStatus.CANCEL || status.getSeverity() == IStatus.ERROR) { return; } // test if VirtualStore is enabled, and enforce elevated target // creation, // because non-elevated writes ZendServer configuration to // VirtualStore, // where it's never read by ZendServer if (EnvironmentUtils.isUnderWindows() && EnvironmentUtils.isUACEnabled()) { throw new PrivilegesException( Messages.LocalTargetDetector_WindowsPriviligesMessage); } try { finalTarget = manager.detectLocalhostTarget(null, null); } catch (IllegalArgumentException e) { finalTarget = detectZendServer6(null); } } catch (PrivilegesException e) { ElevatedProgram prog = ElevatedProgramFactory .getElevatedProgram(); if (prog != null) { runElevated(); } else { status = getError(e.getMessage()); } } catch (DetectionException e) { Throwable cause = e.getCause(); if (e instanceof ServerVersionException) { try { finalTarget.connect(WebApiVersion.V1_3, ServerType.ZEND_SERVER); } catch (WebApiException ex) { cause = ex.getCause(); } catch (LicenseExpiredException ex) { cause = ex.getCause(); } } if (cause instanceof InvalidResponseException) { Shell shell = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(); MessageDialog.openInformation(shell, Messages.LocalTargetDetector_UnsupportedTitle, Messages.LocalTargetDetector_UnsupportedMessage); } } catch (LicenseExpiredException e) { status = getError(e.getMessage()); return; } if (finalTarget == null) { return; } if ((finalTarget.isTemporary()) && (EnvironmentUtils.isUnderLinux())) { Shell shell = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(); ZendDetectTargetCmdLine zcmd = new ZendDetectTargetCmdLine(); String msg; try { msg = zcmd.getFullCommandLine(null, null); } catch (IOException e) { msg = e.getMessage() + Messages.LocalTargetDetector_SeeDocMessage; } MessageDialog.openInformation(shell, Messages.LocalTargetDetector_CompleteTitle, Messages.LocalTargetDetector_CompleteMessage + msg); } } finally { if (finalTarget != null) { ZendTarget t = (ZendTarget) finalTarget; t.setServerName(ZendServerManager.LOCAL_ZEND_SERVER_NAME); finalTarget = TargetsManagerService.INSTANCE.getTargetManager().updateTarget(t, true); } } } private void runElevated() { TargetsManager tm = TargetsManagerService.INSTANCE.getTargetManager(); ElevatedProgram prog = ElevatedProgramFactory.getElevatedProgram(); if (prog != null) { String id = tm.createUniqueId("local"); //$NON-NLS-1$ ZendDetectTargetCmdLine zcmd = new ZendDetectTargetCmdLine(); String key = TargetsManager.DEFAULT_KEY + "." + System.getProperty("user.name"); //$NON-NLS-1$ //$NON-NLS-2$ try { if (!zcmd.runElevated(id, key)) { return; } } catch (IOException e) { StatusManager.getManager().handle( new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e), StatusManager.LOG | StatusManager.SHOW); return; } /* * Elevated target detection may add new target to elevated user * targets list, but all operations that required extra privileges * should be done now, so let's try again to detect target. */ int maxtries = 3; int tries = maxtries; do { if (tries < maxtries) { try { Thread.sleep(3000); } catch (InterruptedException e) { // empty } } try { try { finalTarget = tm.detectLocalhostTarget(id, key, true, false); } catch (IllegalArgumentException e) { detectZendServer6(null); } catch (DetectionException e) { detectZendServer6(null); } catch (LicenseExpiredException e) { status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage()); return; } } catch (DetectionException e) { // ignore } } while (finalTarget == null && (tries-- > 0)); } } private IZendTarget detectZendServer6(final String message) throws DetectionException { ApiKeyDetector manager = new EclipseApiKeyDetector(); try { if (manager.createApiKey(message)) { TargetsManager tm = TargetsManagerService.INSTANCE .getTargetManager(); return tm.detectLocalhostTarget(null, manager.getKey(), manager.getSecretKey()); } else { status = Status.CANCEL_STATUS; } } catch (InvalidCredentialsException e) { return detectZendServer6(Messages.LocalTargetDetector_InvalidCredentialsMessage); } catch (SdkException e) { String msg = e.getMessage(); if (e.getCause() != null) { msg = e.getCause().getMessage(); } status = getError(msg, e); } catch (LicenseExpiredException e) { status = getError(e.getMessage(), e); } return null; } private IStatus getError(String message) { return new Status(IStatus.ERROR, Activator.PLUGIN_ID, message); } private IStatus getError(String message, Exception e) { return new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, e); } }