/******************************************************************************* * Copyright (c) 2017 Alex Xu and others. * 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: * Alex Xu - initial API and implementation *******************************************************************************/ package org.eclipse.php.internal.server.core.builtin; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; 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.Path; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; import org.eclipse.php.internal.server.core.Server; import org.eclipse.php.internal.server.core.manager.ServersManager; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.IRuntime; import org.eclipse.wst.server.core.ServerPort; import org.eclipse.wst.server.core.ServerUtil; import org.eclipse.wst.server.core.model.ServerDelegate; import org.osgi.framework.Version; @SuppressWarnings("restriction") public class PHPServer extends ServerDelegate implements IPHPServer, IPHPServerWorkingCopy { private static final IModule[] EMPTY_LIST = new IModule[0]; public static final String PROPERTY_DEBUG = "debug"; //$NON-NLS-1$ private static final String DEPLOY_DIR = "htdocs"; //$NON-NLS-1$ protected transient PHPServerConfiguration configuration; // Configuration version control private int currentVersion; private int loadedVersion; private Object versionLock = new Object(); public PHPServer() { } @Override public IStatus canModifyModules(IModule[] add, IModule[] remove) { if (add == null || add.length == 0) { return Status.OK_STATUS; } PHPRuntime phpRuntime = getPHPRuntime(); Version runtimeVersion = null; if (phpRuntime != null) { runtimeVersion = Version.parseVersion(phpRuntime.getExecutableInstall().getVersion()); } for (IModule element : add) { IModule module = element; Version moduleVersion = Version.parseVersion(module.getModuleType().getVersion()); if (runtimeVersion != null && runtimeVersion.compareTo(moduleVersion) < 0) { String message = String.format(Messages.PHPServer_incompatible_version, module.getName(), moduleVersion, runtimeVersion); return new Status(IStatus.ERROR, PHPServerPlugin.PLUGIN_ID, 0, message, null); } if (!PHPProjectModule.PHP_MODULE_TYPE_ID.equals(module.getModuleType().getId())) return new Status(IStatus.ERROR, PHPServerPlugin.PLUGIN_ID, 0, Messages.errorWebModulesOnly, null); // if (module.getProject() != null) { // IStatus status = FacetUtil.verifyFacets(module.getProject(), // getServer()); // if (status != null && !status.isOK()) // return status; // } } return Status.OK_STATUS; } @Override public IModule[] getChildModules(IModule[] module) { return EMPTY_LIST; } @Override public IModule[] getRootModules(IModule module) throws CoreException { if ("php.web".equals(module.getModuleType().getId())) { //$NON-NLS-1$ IStatus status = canModifyModules(new IModule[] { module }, null); if (status == null || !status.isOK()) throw new CoreException(status); return new IModule[] { module }; } return EMPTY_LIST; } @Override public void modifyModules(IModule[] add, IModule[] remove, IProgressMonitor monitor) throws CoreException { IStatus status = canModifyModules(add, remove); if (status == null || !status.isOK()) throw new CoreException(status); // TODO implement later // PHPServerConfiguration config = getPHPServerConfiguration(); // // if (add != null) { // int size = add.length; // for (int i = 0; i < size; i++) { // IModule module3 = add[i]; // IWebModule module = (IWebModule) // module3.loadAdapter(IWebModule.class, monitor); // String contextRoot = module.getContextRoot(); // if (contextRoot != null && !contextRoot.startsWith("/") && // contextRoot.length() > 0) // contextRoot = "/" + contextRoot; // String docBase = config.getDocBasePrefix() + module3.getName(); // WebModule module2 = new WebModule(contextRoot, docBase, // module3.getId()); // config.addWebModule(-1, module2); // } // } // // if (remove != null) { // int size2 = remove.length; // for (int j = 0; j < size2; j++) { // IModule module3 = remove[j]; // String memento = module3.getId(); // List modules = getPHPServerConfiguration().getWebModules(); // int size = modules.size(); // for (int i = 0; i < size; i++) { // WebModule module = (WebModule) modules.get(i); // if (memento.equals(module.getMemento())) // config.removeWebModule(i); // } // } // } // config.save(config.getFolder(), monitor); } @Override public ServerPort[] getServerPorts() { if (getServer().getServerConfiguration() == null) return new ServerPort[0]; try { List<ServerPort> list = getPHPServerConfiguration().getServerPorts(); ServerPort[] sp = new ServerPort[list.size()]; list.toArray(sp); return sp; } catch (Exception e) { return new ServerPort[0]; } } @Override public void importRuntimeConfiguration(IRuntime runtime, IProgressMonitor monitor) throws CoreException { // Initialize state synchronized (versionLock) { configuration = null; currentVersion = 0; loadedVersion = 0; } if (runtime == null) { return; } IPath path = runtime.getLocation(); IFolder folder = getServer().getServerConfiguration(); PHPServerConfiguration tcConfig = new DefaultPHPServerConfiguration(folder); try { tcConfig.importFromPath(path, getPHPRuntime().getExecutableInstall(), monitor); } catch (CoreException ce) { throw ce; } // Update version synchronized (versionLock) { // If not already initialized by some other thread, save the // configuration if (configuration == null) { configuration = tcConfig; } } String serverName = getServer().getName(); Server server = ServersManager.getServer(serverName); if (server == null) { try { server = new Server(serverName, getServer().getHost(), getRootUrl().toString(), getDocumentRootDirectory()); ServersManager.addServer(server); ServersManager.save(); } catch (MalformedURLException e) { } } } public IPath getRuntimeBaseDirectory() { return PHPServerHelper.getStandardBaseDirectory(this); } /** * Get the PHP Server runtime for this server. * * @return PHP Server runtime for this server */ public PHPRuntime getPHPRuntime() { if (getServer().getRuntime() == null) return null; return (PHPRuntime) getServer().getRuntime().loadAdapter(PHPRuntime.class, null); } public PHPServerConfiguration getPHPServerConfiguration() throws CoreException { int current; PHPServerConfiguration tcConfig; // Grab current state synchronized (versionLock) { current = currentVersion; tcConfig = configuration; } // If configuration needs loading if (tcConfig == null || loadedVersion != current) { IFolder folder = getServer().getServerConfiguration(); if (folder == null || !folder.exists()) { String path = null; if (folder != null) { path = folder.getFullPath().toOSString(); IProject project = folder.getProject(); if (project != null && project.exists() && !project.isOpen()) throw new CoreException(new Status(IStatus.ERROR, PHPServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorConfigurationProjectClosed, path, project.getName()), null)); } throw new CoreException(new Status(IStatus.ERROR, PHPServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorNoConfiguration, path), null)); } // If not yet loaded if (tcConfig == null) { tcConfig = new DefaultPHPServerConfiguration(folder); } try { tcConfig.load(folder, null); // Update loaded version synchronized (versionLock) { // If newer version not already loaded, update version if (configuration == null || loadedVersion < current) { configuration = tcConfig; loadedVersion = current; } } } catch (CoreException ce) { // Ignore throw ce; } } return tcConfig; } @Override public void saveConfiguration(IProgressMonitor monitor) throws CoreException { PHPServerConfiguration tcConfig = configuration; if (tcConfig == null) return; tcConfig.save(getServer().getServerConfiguration(), monitor); } @Override public void configurationChanged() { synchronized (versionLock) { // Alter the current version currentVersion++; } } /** * Return the root URL of this module. * * @param module * org.eclipse.wst.server.core.model.IModule * @return java.net.URL */ @Override public URL getModuleRootURL(IModule module) { try { if (module == null) return null; PHPServerConfiguration config = getPHPServerConfiguration(); if (config == null) return null; URL url = getRootUrl(); if (url != null) { String path = url.getPath() + config.getWebModuleURL(module); if (!path.endsWith("/")) //$NON-NLS-1$ path += "/"; //$NON-NLS-1$ return new URL(path); } } catch (Exception e) { Trace.trace(Trace.SEVERE, "Could not get root URL", e); //$NON-NLS-1$ } return null; } @Override public void setDocumentRootDirectory(String instanceDir) { setAttribute(PROPERTY_DOCUMENT_ROOT_DIR, instanceDir); } @Override public String getDocumentRootDirectory() { return getAttribute(PROPERTY_DOCUMENT_ROOT_DIR, (String) null); } @Override public void setDefaults(IProgressMonitor monitor) { setAttribute("auto-publish-setting", 2); //$NON-NLS-1$ setAttribute("auto-publish-time", 1); //$NON-NLS-1$ } /** * Gets the directory to which modules should be deployed for this server. * * @return full path to deployment directory for the server */ public IPath getServerDeployDirectory() { IPath deployPath = new Path(DEPLOY_DIR); if (!deployPath.isAbsolute()) { IPath base = getRuntimeBaseDirectory(); deployPath = base.append(deployPath); } return deployPath; } @Override public URL getRootUrl() { try { PHPServerConfiguration config = getPHPServerConfiguration(); if (config == null) return null; String url = "http://" + getServer().getHost(); //$NON-NLS-1$ int port = config.getMainPort().getPort(); port = ServerUtil.getMonitoredPort(getServer(), port, "web"); //$NON-NLS-1$ if (port != 80) url += ":" + port; //$NON-NLS-1$ return new URL(url); } catch (Exception e) { Trace.trace(Trace.SEVERE, "Could not get root URL", e); //$NON-NLS-1$ return null; } } }