/******************************************************************************* * 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.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; 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.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; import org.eclipse.php.internal.debug.core.pathmapper.PathMapper.Mapping; import org.eclipse.php.internal.debug.core.preferences.PHPexeItem; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.ServerPort; /** * PHP server configuration. */ @SuppressWarnings("restriction") public abstract class PHPServerConfiguration implements IPHPServerConfiguration, IPHPServerConfigurationWorkingCopy { public static final String NAME_PROPERTY = "name"; //$NON-NLS-1$ public static final String PORT_PROPERTY = "port"; //$NON-NLS-1$ public static final String MODIFY_PORT_PROPERTY = "modifyPort"; //$NON-NLS-1$ public final static String SERVER_XML_FILENAME = "server.xml"; //$NON-NLS-1$ public final static String PHP_INI_FILENAME = "php.ini"; //$NON-NLS-1$ protected IFolder configPath; // property change listeners private transient List<PropertyChangeListener> propertyListeners; /** * PHPServerConfiguration constructor. * * @param path * a path */ public PHPServerConfiguration(IFolder path) { super(); this.configPath = path; } protected IFolder getFolder() { return configPath; } /** * Copies all files from the given directory in the workbench to the given * location. Can be overridden by version specific class to modify or * enhance what publish does. * * @param phpServerDir * Destination PHP Server root directory. * @param doBackup * Backup existing configuration files (true if not test mode). * @param monitor * Progress monitor to use * @return result of operation */ protected IStatus backupAndPublish(IPath phpServerDir, boolean doBackup, IProgressMonitor monitor) { // Default implementation assumes nothing to do return Status.OK_STATUS; } protected void backupFolder(IFolder folder, IPath confDir, IPath backup, MultiStatus ms, IProgressMonitor monitor) throws CoreException { IResource[] children = folder.members(); if (children == null) return; int size = children.length; monitor.beginTask(Messages.publishConfigurationTask, size * 100); for (int i = 0; i < size; i++) { if (children[i] instanceof IFile) { try { IFile file = (IFile) children[i]; String name = file.getName(); monitor.subTask(NLS.bind(Messages.publisherPublishTask, new String[] { name })); if (Trace.isTraceEnabled()) Trace.trace(Trace.FINEST, "Publishing " + name); //$NON-NLS-1$ // backup and copy file boolean copy = true; if (backup != null && !(backup.append(name).toFile().exists())) { IStatus status = FileUtil.copyFile(confDir.append(name).toOSString(), backup + File.separator + name); ms.add(status); if (!status.isOK()) copy = false; } if (copy) { String destPath = confDir.append(name).toOSString(); String destContents = null; String srcContents = null; File dest = new File(destPath); if (dest.exists()) { InputStream fis = new FileInputStream(destPath); destContents = PHPServerHelper.getFileContents(fis); if (destContents != null) { fis = file.getContents(); srcContents = PHPServerHelper.getFileContents(fis); } } if (destContents == null || srcContents == null || !srcContents.equals(destContents)) { InputStream in = file.getContents(); ms.add(FileUtil.copyFile(in, destPath)); } } } catch (Exception e) { Trace.trace(Trace.SEVERE, "backupAndPublish() error", e); //$NON-NLS-1$ ms.add(new Status(IStatus.ERROR, PHPServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPublishConfiguration, new String[] { e.getLocalizedMessage() }), e)); } } monitor.worked(100); } } protected void backupPath(IPath path, IPath confDir, IPath backup, MultiStatus ms, IProgressMonitor monitor) { File[] files = path.toFile().listFiles(); if (files == null) return; int size = files.length; monitor.beginTask(Messages.publishConfigurationTask, size * 100); for (int i = 0; i < size; i++) { try { File file = files[i]; String name = file.getName(); monitor.subTask(NLS.bind(Messages.publisherPublishTask, new String[] { name })); if (Trace.isTraceEnabled()) Trace.trace(Trace.FINEST, "Publishing " + name); //$NON-NLS-1$ // backup and copy file boolean copy = true; if (backup != null && !(backup.append(name).toFile().exists())) { IStatus status = FileUtil.copyFile(confDir.append(name).toOSString(), backup + File.separator + name); ms.add(status); if (!status.isOK()) copy = false; } if (copy) ms.add(FileUtil.copyFile(file.getAbsolutePath(), confDir.append(name).toOSString())); } catch (Exception e) { Trace.trace(Trace.SEVERE, "backupAndPublish() error", e); //$NON-NLS-1$ ms.add(new Status(IStatus.ERROR, PHPServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPublishConfiguration, new String[] { e.getLocalizedMessage() }), e)); } monitor.worked(100); } } protected IStatus publishContextConfig(IPath baseDir, IPath deployDir, IProgressMonitor monitor) { // Default implementation assumes nothing to do return Status.OK_STATUS; } protected IStatus updateContextsToServeDirectly(IPath baseDir, String phpVersion, String loader, IProgressMonitor monitor) { // Default implementation assumes nothing to do return Status.OK_STATUS; } protected IStatus cleanupServer(IPath confDir, IPath installDir, boolean removeKeptContextFiles, IProgressMonitor monitor) { // Default implementation assumes nothing to clean return Status.OK_STATUS; } /** * Make any local changes to the server configuration at the specified * runtime base directory needed to complete publishing the server. * * @param baseDir * runtime base directory for the server * @param deployDir * deployment directory for the server * @param server * server being localized * @param monitor * a progress monitor * @return result of operation */ public abstract IStatus localizeConfiguration(IPath baseDir, IPath deployDir, PHPServer server, IProgressMonitor monitor); /** * Returns the main server port. * * @return ServerPort */ public abstract ServerPort getMainPort(); public abstract Mapping[] getPathMappings(String moduleName); public abstract Mapping[] getPathMappings(); public abstract void setPathMapping(String moduleName, Mapping[] mappings); /** * Returns the prefix that is used in front of the web module path property. * (e.g. "webapps") * * @return java.lang.String */ public String getDocBasePrefix() { return ""; //$NON-NLS-1$ } /** * Returns the partial URL applicable to this module. * * @param webModule * a web module * @return the partial URL */ protected String getWebModuleURL(IModule webModule) { WebModule module = getWebModule(webModule); if (module != null) return module.getPath(); return null; } /** * Returns the given module from the config. * * @param module * a web module * @return a web module */ public WebModule getWebModule(IModule module) { if (module == null) return null; String memento = module.getId(); List<WebModule> modules = getWebModules(); int size = modules.size(); for (int i = 0; i < size; i++) { WebModule webModule = (WebModule) modules.get(i); if (memento.equals(webModule.getMemento())) { return webModule; } } return null; } protected abstract void save(IFolder folder, IProgressMonitor monitor) throws CoreException; protected void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) { if (propertyListeners == null) return; PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue); try { Iterator<PropertyChangeListener> iterator = propertyListeners.iterator(); while (iterator.hasNext()) { try { PropertyChangeListener listener = (PropertyChangeListener) iterator.next(); listener.propertyChange(event); } catch (Exception e) { Trace.trace(Trace.SEVERE, "Error firing property change event", e); //$NON-NLS-1$ } } } catch (Exception e) { Trace.trace(Trace.SEVERE, "Error in property event", e); //$NON-NLS-1$ } } /** * Adds a property change listener to this server. * * @param listener * java.beans.PropertyChangeListener */ public void addPropertyChangeListener(PropertyChangeListener listener) { if (propertyListeners == null) propertyListeners = new ArrayList<PropertyChangeListener>(); propertyListeners.add(listener); } /** * Removes a property change listener from this server. * * @param listener * java.beans.PropertyChangeListener */ public void removePropertyChangeListener(PropertyChangeListener listener) { if (propertyListeners != null) propertyListeners.remove(listener); } public void importFromPath(IPath path, PHPexeItem phpExeItem, IProgressMonitor monitor) throws CoreException { load(path, phpExeItem, monitor); } protected abstract void load(IPath path, PHPexeItem phpExeItem, IProgressMonitor monitor) throws CoreException; protected abstract void load(IFolder folder, IProgressMonitor monitor) throws CoreException; public abstract void addWebModule(int index, IPHPWebModule module); public abstract void removeWebModule(int index); /** * Gets the work directory for the server. * * @param basePath * path to server runtime directory * @return path for the server's work directory */ public abstract IPath getServerWorkDirectory(IPath basePath); /** * Gets the work directory for the specified module on the server. * * @param basePath * path to server runtime directory * @param module * a PHP web module * @return path for the module's work directory on the server */ public abstract IPath getContextWorkDirectory(IPath basePath, IModule module); /** * Return a string representation of this object. * * @return java.lang.String */ @Override public String toString() { return "PHPServerConfiguration[" + getFolder() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } }