| /******************************************************************************* |
| * Copyright (c) 2003, 2012 IBM Corporation 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: |
| * IBM Corporation - Initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.server.core.internal; |
| |
| import java.util.*; |
| |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.*; |
| import org.eclipse.debug.core.*; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.server.core.*; |
| import org.eclipse.wst.server.core.model.*; |
| |
| /** |
| * |
| */ |
| public class Server extends Base implements IServer { |
| /** |
| * Server id attribute (value "server-id") of launch configurations. |
| * This attribute is used to tag a launch configuration with the |
| * id of the corresponding server. |
| * |
| * @see ILaunchConfiguration |
| */ |
| public static final String ATTR_SERVER_ID = "server-id"; |
| |
| protected static final List<String> EMPTY_LIST = new ArrayList<String>(0); |
| |
| /** |
| * File extension (value "server") for serialized representation of |
| * server instances. |
| * <p> |
| * [issue: What is relationship between this file extension and |
| * the file passed to IServerType.create(...) or returned by |
| * IServer.getFile()? That is, are server files expected to end |
| * in ".server", or is this just a default? If the former |
| * (as I suspect), then IServerType.create needs to say so, |
| * and the implementation should enforce the restriction.] |
| * </p> |
| */ |
| public static final String FILE_EXTENSION = "server"; |
| |
| public static final int AUTO_PUBLISH_DISABLE = 1; |
| public static final int AUTO_PUBLISH_RESOURCE = 2; |
| public static final int AUTO_PUBLISH_BUILD = 3; |
| |
| private static String PUBLISH_AUTO_STRING = "auto"; |
| private static String PUBLISH_CLEAN_STRING = "clean"; |
| private static String PUBLISH_FULL_STRING = "full"; |
| private static String PUBLISH_INCREMENTAL_STRING = "incremental"; |
| private static String PUBLISH_UNKOWN = "unkown"; |
| |
| protected static final String PROP_HOSTNAME = "hostname"; |
| protected static final String SERVER_ID = "server-id"; |
| protected static final String RUNTIME_ID = "runtime-id"; |
| protected static final String CONFIGURATION_ID = "configuration-id"; |
| protected static final String MODULE_LIST = "modules"; |
| protected static final String PROP_DISABLED_PERFERRED_TASKS = "disabled-preferred-publish-tasks"; |
| protected static final String PROP_ENABLED_OPTIONAL_TASKS = "enabled-optional-publish-tasks"; |
| public static final String PROP_PUBLISHERS = "publishers"; |
| public static final String PROP_AUTO_PUBLISH_TIME = "auto-publish-time"; |
| public static final String PROP_AUTO_PUBLISH_SETTING = "auto-publish-setting"; |
| public static final String PROP_START_TIMEOUT = "start-timeout"; |
| public static final String PROP_STOP_TIMEOUT = "stop-timeout"; |
| |
| protected static final char[] INVALID_CHARS = new char[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|', '\0', '@', '&'}; |
| |
| protected IServerType serverType; |
| protected ServerDelegate delegate; |
| protected ServerBehaviourDelegate behaviourDelegate; |
| |
| protected IRuntime runtime; |
| protected IFolder configuration; |
| |
| // the list of modules that are to be published to the server |
| protected List<IModule> modules; |
| |
| /** A lock that is used to synchronize access to modules. */ |
| protected final Object modulesLock = new Object(); |
| |
| // the list of external modules |
| protected List<IModule> externalModules; |
| |
| // transient fields |
| protected transient String mode = ILaunchManager.RUN_MODE; |
| protected transient int serverState = STATE_UNKNOWN; |
| protected transient int serverSyncState; |
| protected transient boolean serverRestartNeeded; |
| |
| protected transient Map<String, Integer> moduleState = new HashMap<String, Integer>(); |
| protected transient Map<String, Integer> modulePublishState = new HashMap<String, Integer>(); |
| protected transient Map<String, Boolean> moduleRestartState = new HashMap<String, Boolean>(); |
| |
| protected transient IStatus serverStatus; |
| protected transient Map<String, IStatus> moduleStatus = new HashMap<String, IStatus>(); |
| |
| protected transient ServerPublishInfo publishInfo; |
| protected transient AutoPublishThread autoPublishThread; |
| |
| /** |
| * The most recent launch used to start the server. |
| */ |
| protected transient ILaunch launch; |
| |
| /* private static final String[] stateStrings = new String[] { |
| "unknown", "starting", "started", "started_debug", |
| "stopping", "stopped", "started_unsupported", "started_profile" |
| };*/ |
| |
| // publish listeners |
| protected transient List<IPublishListener> publishListeners; |
| |
| // server listeners |
| protected transient ServerNotificationManager notificationManager; |
| |
| public class AutoPublishThread extends Thread { |
| public boolean stop; |
| public int time = 0; |
| |
| public AutoPublishThread() { |
| super("Automatic Publishing"); |
| } |
| |
| public void run() { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Auto-publish thread starting for " + Server.this + " - " + time + "s"); |
| } |
| if (stop) |
| return; |
| |
| try { |
| sleep(time * 1000); |
| } catch (Exception e) { |
| // ignore |
| } |
| |
| if (stop) |
| return; |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Auto-publish thread publishing " + Server.this); |
| } |
| |
| if (getServerState() != IServer.STATE_STARTED) |
| return; |
| |
| publish(IServer.PUBLISH_AUTO, null, null, null); |
| } |
| } |
| |
| private abstract class ServerJob extends Job { |
| public ServerJob(String name) { |
| super(name); |
| } |
| |
| public boolean belongsTo(Object family) { |
| return ServerUtil.SERVER_JOB_FAMILY.equals(family); |
| } |
| |
| public IServer getServer() { |
| return Server.this; |
| } |
| } |
| |
| public class ResourceChangeJob extends ServerJob { |
| private IModule module; |
| private IResourceChangeEvent event; |
| |
| public ResourceChangeJob(IModule module) { |
| this(module, null); |
| } |
| |
| public ResourceChangeJob(IModule module, IResourceChangeEvent event) { |
| super(NLS.bind(Messages.jobUpdateServer, Server.this.getName())); |
| this.module = module; |
| this.event = event; |
| |
| if (module.getProject() == null) |
| setRule(Server.this); |
| else { |
| ISchedulingRule[] rules = new ISchedulingRule[2]; |
| IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory(); |
| rules[0] = ruleFactory.createRule(module.getProject()); |
| rules[1] = Server.this; |
| setRule(MultiRule.combine(rules)); |
| } |
| } |
| |
| protected IModule getModule() { |
| return module; |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) { |
| final boolean[] changed = new boolean[1]; |
| final List<IModule[]> modules2 = new ArrayList<IModule[]>(); |
| |
| // create the visitor that will reset the module publish state flag |
| IModuleVisitor visitor = new IModuleVisitor() { |
| public boolean visit(IModule[] module2) { |
| modules2.add(module2); |
| |
| int size = module2.length; |
| IModule m = module2[size - 1]; |
| if (m.getProject() == null) |
| return true; |
| |
| if (getModule().equals(m)) { |
| if (hasPublishedResourceDelta(module2)) { |
| changed[0] = true; |
| int newState = getModulePublishState(module2) == IServer.PUBLISH_STATE_FULL ? IServer.PUBLISH_STATE_FULL : IServer.PUBLISH_STATE_INCREMENTAL; |
| setModulePublishState(module2, newState); |
| } |
| } |
| return true; |
| } |
| }; |
| |
| // run the visitor |
| visit(visitor, null); |
| |
| if (getServerPublishInfo().hasStructureChanged(modules2)) { |
| int newState = getServerPublishState() == IServer.PUBLISH_STATE_FULL ? IServer.PUBLISH_STATE_FULL : IServer.PUBLISH_STATE_INCREMENTAL; |
| setServerPublishState(newState); |
| } |
| |
| if (!changed[0]) |
| return Status.OK_STATUS; |
| |
| if (getServerState() != IServer.STATE_STOPPED && behaviourDelegate != null) |
| behaviourDelegate.handleResourceChange(); |
| |
| if (getServerState() == IServer.STATE_STARTED) |
| autoPublish(event); |
| |
| return Status.OK_STATUS; |
| } |
| } |
| |
| public final class PublishJob extends ServerJob { |
| private final int kind; |
| private final List<IModule[]> modules4; |
| private final IAdaptable info; |
| private final boolean start; |
| |
| /** |
| * Create a new publishing job. |
| * |
| * @param kind the kind of publish |
| * @param modules4 a list of modules to publish, or <code>null</code> to |
| * publish all modules |
| * @param start true if we need to start the server first |
| * @param info the IAdaptable (or <code>null</code>) provided by the |
| * caller in order to supply UI information for prompting the |
| * user if necessary. When this parameter is not |
| * <code>null</code>, it should minimally contain an adapter |
| * for the Shell class. |
| */ |
| public PublishJob(int kind, List<IModule[]> modules4, boolean start, IAdaptable info) { |
| super(NLS.bind(Messages.publishing, Server.this.getName())); |
| this.kind = kind; |
| this.modules4 = modules4; |
| this.start = start; |
| this.info = info; |
| } |
| |
| /** |
| * Returns the list of projects that requires to be locked during a publish. |
| * @return the list of projects |
| */ |
| @SuppressWarnings("synthetic-access") |
| List<IProject> getProjectPublishLockList(IProgressMonitor monitor) { |
| final List<IProject> projectPublishLockList = new ArrayList<IProject>(); |
| |
| IModule[] curModules = getModules(); |
| // Check empty module list since the visitModule does not handle that properly. |
| if (curModules != null && curModules.length > 0) { |
| for (IModule curModule: curModules) { |
| // Get all the affected projects during the publish. |
| visitModule(new IModule[] { curModule }, new IModuleVisitor(){ |
| public boolean visit(IModule[] modules2) { |
| for (IModule curModule2 : modules2) { |
| IProject curProject = curModule2.getProject(); |
| if (curProject != null) { |
| if (!projectPublishLockList.contains(curProject)) { |
| projectPublishLockList.add(curProject); |
| } |
| } |
| } |
| return true; |
| }}, monitor); |
| } |
| } |
| return projectPublishLockList; |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) { |
| if (start) { |
| try{ |
| // 237222 - Apply the rules only when the job has started |
| Job.getJobManager().beginRule(Server.this, monitor); |
| IStatus status = startImpl(ILaunchManager.RUN_MODE, monitor); |
| if (status != null && status.getSeverity() == IStatus.ERROR) |
| return status; |
| } |
| finally{ |
| Job.getJobManager().endRule(Server.this); |
| } |
| } |
| |
| ServerDelegate curDelegate = getDelegate(monitor); |
| ISchedulingRule[] publishScheduleRules = null; |
| if (curDelegate != null && curDelegate.isUseProjectSpecificSchedulingRuleOnPublish()) { |
| // 288863 - lock only affected projects during publish |
| // Find out all the projects that contains modules added to this server for workspace lock. |
| List<IProject> curProjectPublishLockList = getProjectPublishLockList(monitor); |
| |
| publishScheduleRules = new ISchedulingRule[curProjectPublishLockList.size()+1]; |
| IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory(); |
| publishScheduleRules[0] = Server.this; |
| int i=1; |
| for (IProject curProj : curProjectPublishLockList) { |
| publishScheduleRules[i++] = ruleFactory.modifyRule(curProj); |
| } |
| } else { |
| // 102227 - lock entire workspace during publish |
| publishScheduleRules = new ISchedulingRule[] { |
| ResourcesPlugin.getWorkspace().getRoot(), Server.this |
| }; |
| } |
| ISchedulingRule publishRule = MultiRule.combine(publishScheduleRules); |
| |
| try{ |
| // 237222 - Apply the rules only when the job has started |
| Job.getJobManager().beginRule(publishRule, monitor); |
| return publishImpl(kind, modules4, info, monitor); |
| } finally { |
| Job.getJobManager().endRule(publishRule); |
| } |
| } |
| } |
| |
| public class StartJob extends ServerJob { |
| protected static final byte PUBLISH_NONE = 0; |
| protected static final byte PUBLISH_BEFORE = 1; |
| protected static final byte PUBLISH_AFTER = 2; |
| |
| protected String launchMode; |
| |
| public StartJob(String launchMode) { |
| super(NLS.bind(Messages.jobStarting, Server.this.getName())); |
| this.launchMode = launchMode; |
| |
| setRule(Server.this); |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) { |
| IStatus stat = startImpl(launchMode, monitor); |
| return stat; |
| } |
| } |
| |
| public class RestartJob extends ServerJob { |
| protected String launchMode; |
| |
| public RestartJob(String launchMode) { |
| super(NLS.bind(Messages.jobRestarting, Server.this.getName())); |
| this.launchMode = launchMode; |
| setRule(Server.this); |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) { |
| return restartImpl(launchMode, monitor); |
| } |
| } |
| |
| public class StopJob extends ServerJob { |
| protected boolean force; |
| |
| public StopJob(boolean force) { |
| super(NLS.bind(Messages.jobStopping, Server.this.getName())); |
| setRule(Server.this); |
| this.force = force; |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) { |
| return stopImpl(force, monitor); |
| } |
| } |
| |
| private static final Comparator<PublishOperation> PUBLISH_OPERATION_COMPARTOR = new Comparator<PublishOperation>() { |
| public int compare(PublishOperation leftOp, PublishOperation rightOp) { |
| PublishOperation left = leftOp; |
| PublishOperation right = rightOp; |
| if (left.getOrder() > right.getOrder()) |
| return 1; |
| if (left.getOrder() < right.getOrder()) |
| return -1; |
| return 0; |
| } |
| }; |
| |
| // working copy, loaded resource |
| public Server(IFile file) { |
| super(file); |
| map.put(PROP_HOSTNAME, "localhost"); |
| } |
| |
| // creation (working copy) |
| public Server(String id, IFile file, IRuntime runtime, IServerType serverType) { |
| super(file, id); |
| this.runtime = runtime; |
| this.serverType = serverType; |
| map.put("server-type-id", serverType.getId()); |
| map.put(PROP_HOSTNAME, "localhost"); |
| map.put(PROP_START_TIMEOUT, ((ServerType)serverType).getStartTimeout()/1000 + ""); |
| map.put(PROP_STOP_TIMEOUT, ((ServerType)serverType).getStopTimeout()/1000 + ""); |
| if (runtime != null && runtime.getRuntimeType() != null) { |
| String name = runtime.getRuntimeType().getName(); |
| map.put(PROP_NAME, name); |
| } |
| serverState = ((ServerType)serverType).getInitialState(); |
| } |
| |
| public IServerType getServerType() { |
| return serverType; |
| } |
| |
| public IServerWorkingCopy createWorkingCopy() { |
| return new ServerWorkingCopy(this); |
| } |
| |
| public boolean isWorkingCopy() { |
| return false; |
| } |
| |
| protected void deleteFromFile() throws CoreException { |
| super.deleteFromFile(); |
| ResourceManager.getInstance().removeServer(this); |
| } |
| |
| protected void deleteFromMetadata() { |
| ResourceManager.getInstance().removeServer(this); |
| } |
| |
| protected void doSave(IProgressMonitor monitor) throws CoreException { |
| super.doSave(monitor); |
| fireServerChangeEvent(); |
| } |
| |
| protected void saveToFile(IProgressMonitor monitor) throws CoreException { |
| super.saveToFile(monitor); |
| ResourceManager.getInstance().addServer(this); |
| } |
| |
| protected void saveToMetadata(IProgressMonitor monitor) { |
| super.saveToMetadata(monitor); |
| ResourceManager.getInstance().addServer(this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServerAttributes#getRuntime() |
| */ |
| public IRuntime getRuntime() { |
| return runtime; |
| } |
| |
| protected String getRuntimeId() { |
| return getAttribute(RUNTIME_ID, (String) null); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServerAttributes#getServerConfiguration() |
| */ |
| public IFolder getServerConfiguration() { |
| return configuration; |
| } |
| |
| protected ServerDelegate getDelegate(IProgressMonitor monitor) { |
| if (delegate != null || serverType == null) |
| return delegate; |
| |
| synchronized (this) { |
| if (delegate == null) { |
| try { |
| long time = System.currentTimeMillis(); |
| delegate = ((ServerType) serverType).createServerDelegate(); |
| if (delegate != null) |
| InternalInitializer.initializeServerDelegate(delegate, Server.this, monitor); |
| if (Trace.PERFORMANCE) { |
| Trace.trace(Trace.STRING_PERFORMANCE, "Server.getDelegate(): <" |
| + (System.currentTimeMillis() - time) + "> " + getServerType().getId()); |
| } |
| } catch (Throwable t) { |
| ServerPlugin.logExtensionFailure(toString(), t); |
| } |
| } |
| } |
| return delegate; |
| } |
| |
| protected ServerBehaviourDelegate getBehaviourDelegate(IProgressMonitor monitor) { |
| if (behaviourDelegate != null || serverType == null) |
| return behaviourDelegate; |
| |
| synchronized (moduleState) { |
| if (behaviourDelegate == null) { |
| try { |
| long time = System.currentTimeMillis(); |
| behaviourDelegate = ((ServerType) serverType).createServerBehaviourDelegate(); |
| if (behaviourDelegate != null) |
| InternalInitializer.initializeServerBehaviourDelegate(behaviourDelegate, Server.this, monitor); |
| if (Trace.PERFORMANCE) { |
| Trace.trace(Trace.STRING_PERFORMANCE, |
| "Server.getBehaviourDelegate(): <" + (System.currentTimeMillis() - time) + "> " |
| + getServerType().getId()); |
| } |
| |
| // publish only if the server is started but respect Server > Launching > PREF_AUTO_PUBLISH |
| if (getServerState() == IServer.STATE_STARTED && ServerCore.isAutoPublishing()) |
| autoPublish(); |
| } catch (Throwable t) { |
| ServerPlugin.logExtensionFailure(toString(), t); |
| } |
| } |
| } |
| return behaviourDelegate; |
| } |
| |
| public void dispose() { |
| if (delegate != null) { |
| delegate.dispose(); |
| delegate = null; |
| } |
| if (behaviourDelegate != null) { |
| behaviourDelegate.dispose(); |
| behaviourDelegate = null; |
| } |
| } |
| |
| public String getHost() { |
| return getAttribute(PROP_HOSTNAME, "localhost"); |
| } |
| |
| public int getAutoPublishTime() { |
| return getAttribute(PROP_AUTO_PUBLISH_TIME, 15); |
| } |
| |
| public int getAutoPublishSetting() { |
| return getAttribute(PROP_AUTO_PUBLISH_SETTING, AUTO_PUBLISH_RESOURCE); |
| } |
| |
| public int getStartTimeout() { |
| return getAttribute(PROP_START_TIMEOUT, ((ServerType)getServerType()).getStartTimeout()/1000); |
| } |
| |
| public int getStopTimeout() { |
| return getAttribute(PROP_STOP_TIMEOUT, ((ServerType)getServerType()).getStopTimeout()/1000); |
| } |
| |
| /** |
| * Returns a list of id (String) of preferred publish operations that will not be run |
| * during publish. |
| * |
| * @return a list of publish operation ids |
| */ |
| public List<String> getDisabledPreferredPublishOperationIds() { |
| return getAttribute(PROP_DISABLED_PERFERRED_TASKS, EMPTY_LIST); |
| } |
| |
| /** |
| * Returns a list of id (String) of optional publish operations that are enabled to |
| * be run during publish. |
| * |
| * @return a list of publish operation ids |
| */ |
| public List<String> getEnabledOptionalPublishOperationIds() { |
| return getAttribute(PROP_ENABLED_OPTIONAL_TASKS, EMPTY_LIST); |
| } |
| |
| /** |
| * Returns a list of id (String) of publishers and state (true or false). |
| * |
| * @return a list of publishers |
| */ |
| public List<String> getPublisherIds() { |
| return getAttribute(PROP_PUBLISHERS, EMPTY_LIST); |
| } |
| |
| public boolean isPublisherEnabled(Publisher pub) { |
| if (pub == null) |
| return false; |
| |
| // check for existing enablement |
| List<String> list = getAttribute(PROP_PUBLISHERS, EMPTY_LIST); |
| Iterator<String> iter = list.iterator(); |
| while (iter.hasNext()) { |
| String id = iter.next(); |
| int ind = id.indexOf(":"); |
| boolean enabled = false; |
| if ("true".equals(id.substring(ind+1))) |
| enabled = true; |
| id = id.substring(0, ind); |
| if (pub.getId().equals(id)) |
| return enabled; |
| } |
| |
| // otherwise use the default enablement |
| return true; |
| } |
| |
| /** |
| * Returns the current state of the server. (see SERVER_XXX constants) |
| * |
| * @return int |
| */ |
| public int getServerState() { |
| return serverState; |
| } |
| |
| public String getMode() { |
| return mode; |
| } |
| |
| public void setServerState(int state) { |
| if (state == serverState) |
| return; |
| |
| // ensure that any server monitors are started |
| if (state == IServer.STATE_STARTED) |
| ServerMonitorManager.getInstance(); |
| |
| this.serverState = state; |
| fireServerStateChangeEvent(); |
| } |
| |
| /** |
| * Add a listener to this server. |
| * |
| * @param listener org.eclipse.wst.server.model.IServerListener |
| */ |
| public void addServerListener(IServerListener listener) { |
| if (listener == null) |
| throw new IllegalArgumentException("Module cannot be null"); |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "Adding server listener " + listener + " to " + this); |
| } |
| getServerNotificationManager().addListener(listener); |
| } |
| |
| /** |
| * Add a listener to this server with the given event mask. |
| * |
| * @param listener org.eclipse.wst.server.model.IServerListener |
| * @param eventMask to limit listening to certain types of events |
| */ |
| public void addServerListener(IServerListener listener, int eventMask) { |
| if (listener == null) |
| throw new IllegalArgumentException("Module cannot be null"); |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "Adding server listener " + listener + " to " + this |
| + " with eventMask " + eventMask); |
| } |
| getServerNotificationManager().addListener(listener, eventMask); |
| } |
| |
| /** |
| * Remove a listener from this server. |
| * |
| * @param listener org.eclipse.wst.server.model.IServerListener |
| */ |
| public void removeServerListener(IServerListener listener) { |
| if (listener == null) |
| throw new IllegalArgumentException("Module cannot be null"); |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "Removing server listener " + listener + " from " + this); |
| } |
| getServerNotificationManager().removeListener(listener); |
| } |
| |
| /** |
| * Fire a server listener restart state change event. |
| */ |
| protected void fireRestartStateChangeEvent() { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing server restart change event: " + getName() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.SERVER_CHANGE | ServerEvent.RESTART_STATE_CHANGE, this, getServerState(), |
| getServerPublishState(), getServerRestartState())); |
| } |
| |
| /** |
| * Fire a server listener server status change event |
| */ |
| protected void fireServerStatusChangeEvent() { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing server status change event: " + getName() + ", " |
| + getServerStatus() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.SERVER_CHANGE | ServerEvent.STATUS_CHANGE, this, getServerState(), |
| getServerPublishState(), getServerRestartState(), getServerStatus())); |
| } |
| |
| /** |
| * Fire a server listener state change event. |
| */ |
| protected void fireServerStateChangeEvent() { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing server state change event: " + getName() + ", " |
| + getServerState() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.SERVER_CHANGE | ServerEvent.STATE_CHANGE, this, getServerState(), |
| getServerPublishState(), getServerRestartState())); |
| } |
| |
| /** |
| * Fire a server listener change event. |
| */ |
| protected void fireServerChangeEvent() { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing server change event: " + getName() + ", " |
| + getServerState() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.SERVER_CHANGE, this, getServerState(), |
| getServerPublishState(), getServerRestartState())); |
| } |
| |
| /** |
| * Fire a server listener module state change event. |
| */ |
| protected void fireModuleStateChangeEvent(IModule[] module) { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing module state change event: " + getName() + ", " |
| + getServerState() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.MODULE_CHANGE | ServerEvent.STATE_CHANGE, this, module, getModuleState(module), |
| getModulePublishState(module), getModuleRestartState(module))); |
| } |
| |
| |
| /** |
| * Fire a server listener module status change event. |
| */ |
| protected void fireModuleStatusChangeEvent(IModule[] module) { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing module status change event: " + getName() + ", " |
| + getModuleStatus(module) + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.MODULE_CHANGE | ServerEvent.STATUS_CHANGE, this, module, getModuleState(module), |
| getModulePublishState(module), getModuleRestartState(module), getModuleStatus(module))); |
| } |
| |
| /** |
| * Fire a server listener module publish state change event. |
| */ |
| protected void fireModulePublishStateChangeEvent(IModule[] module) { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing module publish state change event: " + getName() + ", " |
| + getServerState() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.MODULE_CHANGE | ServerEvent.PUBLISH_STATE_CHANGE, this, module, getModuleState(module), |
| getModulePublishState(module), getModuleRestartState(module))); |
| } |
| |
| /** |
| * Fire a server listener module state change event. |
| */ |
| protected void fireModuleRestartChangeEvent(IModule[] module) { |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "->- Firing module restart change event: " + getName() + ", " |
| + getServerState() + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.MODULE_CHANGE | ServerEvent.RESTART_STATE_CHANGE, this, module, getModuleState(module), |
| getModulePublishState(module), getModuleRestartState(module))); |
| } |
| |
| public void setMode(String m) { |
| if (m == mode) |
| return; |
| |
| this.mode = m; |
| fireServerStateChangeEvent(); |
| } |
| |
| public void setModuleState(IModule[] module, int state) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| int oldState = getModuleState(module); |
| if (oldState == state) |
| return; |
| |
| Integer in = new Integer(state); |
| moduleState.put(getKey(module), in); |
| fireModuleStateChangeEvent(module); |
| } |
| |
| public void setModulePublishState(IModule[] module, int state) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| int oldState = getModulePublishState(module); |
| if (oldState == state) |
| return; |
| |
| Integer in = new Integer(state); |
| if (state == -1) |
| modulePublishState.remove(getKey(module)); |
| modulePublishState.put(getKey(module), in); |
| fireModulePublishStateChangeEvent(module); |
| } |
| |
| public void setModuleRestartState(IModule[] module, boolean r) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| boolean oldState = getModuleRestartState(module); |
| if (oldState == r) |
| return; |
| |
| Boolean b = new Boolean(r); |
| moduleRestartState.put(getKey(module), b); |
| fireModuleRestartChangeEvent(module); |
| } |
| |
| public void setExternalModules(IModule[] modules) { |
| externalModules = new ArrayList<IModule>(); |
| if (modules != null) { |
| int size = modules.length; |
| for (int i = 0; i < size; i++) |
| externalModules.add(modules[i]); |
| } |
| } |
| |
| public List<IModule> getExternalModules() { |
| return externalModules; |
| } |
| |
| protected void handleModuleProjectChange(IModule module) { |
| handleModuleProjectChange(module, null); |
| } |
| |
| protected void handleModuleProjectChange(IModule module, IResourceChangeEvent buildEvent) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "> handleDeployableProjectChange() " + this + " " + module); |
| } |
| |
| if (!isModuleDeployed(module)){ |
| return; |
| } |
| |
| // check for duplicate jobs already waiting and don't create a new one |
| Job[] jobs = Job.getJobManager().find(ServerUtil.SERVER_JOB_FAMILY); |
| if (jobs != null) { |
| int size = jobs.length; |
| for (int i = 0; i < size; i++) { |
| if (jobs[i] instanceof ResourceChangeJob) { |
| ResourceChangeJob rcj = (ResourceChangeJob) jobs[i]; |
| if (rcj.getServer().equals(this) && rcj.getModule().equals(module) && rcj.getState() == Job.WAITING) |
| return; |
| } |
| } |
| } |
| |
| ResourceChangeJob job = new ResourceChangeJob(module, buildEvent); |
| job.setSystem(true); |
| job.setPriority(Job.BUILD); |
| job.schedule(); |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "< handleDeployableProjectChange()"); |
| } |
| } |
| |
| protected boolean isModuleDeployed(final IModule requestedModule){ |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "> isModuleDeployed()"); |
| } |
| |
| // no modules are deployed |
| if (getModules().length < 0) |
| return false; |
| |
| boolean deployed = false; |
| |
| synchronized (modulesLock){ |
| // shallow search: check for root modules first |
| if (modules != null){ |
| deployed = modules.contains(requestedModule); |
| |
| if(!deployed){ |
| // deep search: look into all the child modules |
| Iterator<IModule> itr = modules.iterator(); |
| while(itr.hasNext() && !deployed){ |
| IModule[] m = new IModule[] {itr.next()}; |
| deployed = !visitModule(m, new IModuleVisitor(){ |
| public boolean visit(IModule[] modules2) { |
| for (int i =0;i<=modules2.length-1;i++){ |
| if (modules2[i].equals(requestedModule)) |
| return false; |
| } |
| return true; |
| }}, null); |
| } |
| } |
| } |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "< isModuleDeployed() deployed=" + deployed); |
| } |
| return deployed; |
| } |
| |
| protected void stopAutoPublish() { |
| if (autoPublishThread == null) |
| return; |
| |
| autoPublishThread.stop = true; |
| autoPublishThread.interrupt(); |
| autoPublishThread = null; |
| } |
| |
| /** |
| * Reset automatic publish thread if it is running and start a new |
| * thread if automatic publishing is currently enabled. |
| */ |
| protected void autoPublish() { |
| autoPublish(null); |
| } |
| |
| protected void autoPublish(IResourceChangeEvent event) { |
| stopAutoPublish(); |
| boolean buildOccurred = event != null && didBuildOccur(event); |
| boolean projectClosedOrDeleted = event != null && isProjectCloseOrDeleteEvent(event); |
| |
| if (getAutoPublishSetting() == AUTO_PUBLISH_DISABLE) |
| return; |
| |
| if( (getAutoPublishSetting() == AUTO_PUBLISH_BUILD) && |
| !buildOccurred && !projectClosedOrDeleted) |
| return; |
| |
| int time = getAutoPublishTime(); |
| if (time >= 0) { |
| autoPublishThread = new AutoPublishThread(); |
| autoPublishThread.time = time; |
| autoPublishThread.setPriority(Thread.MIN_PRIORITY + 1); |
| autoPublishThread.setDaemon(true); |
| autoPublishThread.start(); |
| } |
| } |
| |
| private boolean isProjectCloseOrDeleteEvent(IResourceChangeEvent event) { |
| int kind = event.getType(); |
| if( (kind & IResourceChangeEvent.PRE_CLOSE) > 0 || |
| (kind & IResourceChangeEvent.PRE_DELETE) > 0) |
| return true; |
| return false; |
| } |
| |
| private boolean didBuildOccur(IResourceChangeEvent event) { |
| int kind = event.getBuildKind(); |
| final boolean eventOccurred = |
| (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD) || |
| (kind == IncrementalProjectBuilder.FULL_BUILD) || |
| ((kind == IncrementalProjectBuilder.AUTO_BUILD && |
| ResourcesPlugin.getWorkspace().isAutoBuilding())); |
| return eventOccurred; |
| } |
| |
| /** |
| * Returns the event notification manager. |
| * |
| * @return the notification manager |
| */ |
| private ServerNotificationManager getServerNotificationManager() { |
| if (notificationManager == null) |
| notificationManager = new ServerNotificationManager(); |
| |
| return notificationManager; |
| } |
| |
| /** |
| * Returns the server's publish sync state. |
| * |
| * @return int |
| */ |
| public int getServerPublishState() { |
| return serverSyncState; |
| } |
| |
| /** |
| * Sets the server's publish sync state. |
| * |
| * @param state int |
| */ |
| public void setServerPublishState(int state) { |
| if (state == serverSyncState) |
| return; |
| serverSyncState = state; |
| firePublishStateChange(); |
| } |
| |
| /** |
| * Adds a publish listener to this server. |
| * Has no effect if an identical listener is already registered. |
| * |
| * @param listener the publish listener |
| * @see #removePublishListener(IPublishListener) |
| */ |
| public void addPublishListener(IPublishListener listener) { |
| if (listener == null) |
| throw new IllegalArgumentException("Listener cannot be null"); |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "Adding publish listener " + listener + " to " + this); |
| } |
| |
| if (publishListeners == null) |
| publishListeners = new ArrayList<IPublishListener>(); |
| publishListeners.add(listener); |
| } |
| |
| /** |
| * Removes a publish listener from this server. |
| * Has no effect if the listener is not registered. |
| * |
| * @param listener the publish listener |
| * @see #addPublishListener(IPublishListener) |
| */ |
| public void removePublishListener(IPublishListener listener) { |
| if (listener == null) |
| throw new IllegalArgumentException("Listener cannot be null"); |
| if (Trace.LISTENERS) { |
| Trace.trace(Trace.STRING_LISTENERS, "Removing publish listener " + listener + " from " + this); |
| } |
| |
| if (publishListeners != null) |
| publishListeners.remove(listener); |
| } |
| |
| /** |
| * Fire a publish start event. |
| */ |
| protected void firePublishStarted() { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "->- Firing publish started event ->-"); |
| } |
| |
| if (publishListeners == null || publishListeners.isEmpty()) |
| return; |
| |
| int size = publishListeners.size(); |
| IPublishListener[] srl = new IPublishListener[size]; |
| publishListeners.toArray(srl); |
| |
| for (int i = 0; i < size; i++) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, " Firing publish started event to " + srl[i]); |
| } |
| try { |
| srl[i].publishStarted(this); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace( |
| Trace.STRING_SEVERE, |
| " Error firing publish started event to " + srl[i], |
| e); |
| } |
| } |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "-<- Done firing publish started event -<-"); |
| } |
| } |
| |
| /** |
| * Fire a publish stop event. |
| * |
| * @param status publishing status |
| */ |
| protected void firePublishFinished(IStatus status) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "->- Firing publishing finished event: " + status + " ->-"); |
| } |
| |
| if (publishListeners == null || publishListeners.isEmpty()) |
| return; |
| |
| int size = publishListeners.size(); |
| IPublishListener[] srl = new IPublishListener[size]; |
| publishListeners.toArray(srl); |
| |
| for (int i = 0; i < size; i++) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, " Firing publishing finished event to " + srl[i]); |
| } |
| try { |
| srl[i].publishFinished(this, status); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| " Error firing publishing finished event to " |
| + srl[i], e); |
| } |
| } |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "-<- Done firing publishing finished event -<-"); |
| } |
| } |
| |
| /** |
| * Fire a publish state change event. |
| */ |
| protected void firePublishStateChange() { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "->- Firing publish state change event ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.SERVER_CHANGE | ServerEvent.PUBLISH_STATE_CHANGE, this, getServerState(), |
| getServerPublishState(), getServerRestartState())); |
| } |
| |
| /** |
| * Fire a publish state change event. |
| */ |
| protected void firePublishStateChange(IModule[] module) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "->- Firing publish state change event: " + module + " ->-"); |
| } |
| |
| if (notificationManager == null || notificationManager.hasNoListeners()) |
| return; |
| |
| notificationManager.broadcastChange( |
| new ServerEvent(ServerEvent.MODULE_CHANGE | ServerEvent.PUBLISH_STATE_CHANGE, this, module, getModuleState(module), |
| getModulePublishState(module), getModuleRestartState(module))); |
| } |
| |
| /** |
| * Returns true if the server is in a state that it can |
| * be published to. |
| * |
| * @return boolean |
| */ |
| public IStatus canPublish() { |
| if (getServerType() == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null); |
| |
| // can't publish if the server is starting or stopping |
| int state = getServerState(); |
| if (state == STATE_STARTING || state == STATE_STOPPING) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishStarting, null); |
| |
| // can't publish if there is no configuration |
| if (getServerType().hasServerConfiguration() && configuration == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishNoConfiguration, null); |
| |
| if (getBehaviourDelegate(new NullProgressMonitor()) != null) |
| return getBehaviourDelegate(new NullProgressMonitor()).canPublish(); |
| |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Returns true if the server should be published to. This is <code>true</code> when the server |
| * can be published to and the server's publish state or any module's publish state is not |
| * PUBLISH_STATE_NONE. |
| * |
| * @return boolean |
| */ |
| public boolean shouldPublish() { |
| if (!canPublish().isOK()) |
| return false; |
| |
| if (getServerPublishState() != PUBLISH_STATE_NONE) |
| return true; |
| |
| final boolean[] publish = new boolean[1]; |
| |
| visit(new IModuleVisitor() { |
| public boolean visit(IModule[] module) { |
| if (getModulePublishState(module) != PUBLISH_STATE_NONE) { |
| publish[0] = true; |
| return false; |
| } |
| return true; |
| } |
| }, null); |
| |
| return publish[0]; |
| } |
| |
| public boolean isPublishUnknown() { |
| if (getServerPublishState() != PUBLISH_STATE_UNKNOWN) |
| return false; |
| |
| final boolean[] publish = new boolean[1]; |
| publish[0] = true; |
| |
| visit(new IModuleVisitor() { |
| public boolean visit(IModule[] module) { |
| if (getModulePublishState(module) != PUBLISH_STATE_UNKNOWN) { |
| publish[0] = false; |
| return false; |
| } |
| return true; |
| } |
| }, null); |
| |
| return publish[0]; |
| } |
| |
| /** |
| * Returns true if the server should be restarted. This is <code>true</code> when the server |
| * can be restarted and the server's restart state or any module's restart states is not |
| * false. |
| * |
| * @return boolean |
| */ |
| public boolean shouldRestart() { |
| if (!canPublish().isOK()) |
| return false; |
| |
| if (getServerRestartState()) |
| return true; |
| |
| final boolean[] publish = new boolean[1]; |
| |
| visit(new IModuleVisitor() { |
| public boolean visit(IModule[] module) { |
| if (getModuleRestartState(module)) { |
| publish[0] = true; |
| return false; |
| } |
| return true; |
| } |
| }, null); |
| |
| return publish[0]; |
| } |
| |
| public ServerPublishInfo getServerPublishInfo() { |
| if (publishInfo == null) { |
| publishInfo = PublishInfo.getInstance().getServerPublishInfo(this); |
| } |
| return publishInfo; |
| } |
| |
| /* |
| * Publish to the server using the progress monitor. The result of the |
| * publish operation is returned as an IStatus. |
| */ |
| public IStatus publish(int kind, IProgressMonitor monitor) { |
| if (getServerType() == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null); |
| |
| // check what is out of sync and publish |
| if (getServerType().hasServerConfiguration() && configuration == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorNoConfiguration, null); |
| |
| // make sure that the delegate is loaded and the server state is correct |
| loadAdapter(ServerBehaviourDelegate.class, monitor); |
| |
| if (((ServerType)getServerType()).startBeforePublish() && (getServerState() == IServer.STATE_STOPPED)) { |
| IStatus status = startImpl(ILaunchManager.RUN_MODE, monitor); |
| if (status != null && status.getSeverity() == IStatus.ERROR) |
| return status; |
| } |
| |
| return publishImpl(kind, null, null, monitor); |
| } |
| |
| /* |
| * Publish the given modules to the server. |
| * TODO: Implementation of publishing individual modules! |
| */ |
| public void publish(final int kind, final List<IModule[]> modules2, final IAdaptable info, final IOperationListener opListener) { |
| if (getServerType() == null) { |
| if (opListener != null) |
| opListener.done(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null)); |
| return; |
| } |
| |
| // check what is out of sync and publish |
| if (getServerType().hasServerConfiguration() && configuration == null) { |
| if (opListener != null) |
| opListener.done(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorNoConfiguration, null)); |
| return; |
| } |
| |
| // make sure that the delegate is loaded and the server state is correct |
| loadAdapter(ServerBehaviourDelegate.class, null); |
| |
| boolean start = false; |
| if (((ServerType)getServerType()).startBeforePublish() && (getServerState() == IServer.STATE_STOPPED)) |
| start = true; |
| |
| PublishJob publishJob = new PublishJob(kind, modules2, start, info); |
| if (opListener != null) { |
| publishJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| |
| // to make the publishing dialog appear, require adaptable to covert String.class |
| // into "user" string. a bit of a kludge, but works fine for now |
| if (info != null && "user".equals(info.getAdapter(String.class))) |
| publishJob.setUser(true); |
| publishJob.schedule(); |
| } |
| |
| /** |
| * Returns the publish tasks that have been targeted to this server. |
| * These tasks should be run during publishing and will be initialized |
| * with a task model. |
| * |
| * @param kind one of the IServer.PUBLISH_XX constants |
| * @param moduleList a list of modules |
| * @param kindList one of the IServer publish change constants |
| * @return a possibly empty array of IOptionalTasks |
| */ |
| public PublishOperation[] getTasks(int kind, List moduleList, List kindList) { |
| List<PublishOperation> tasks = new ArrayList<PublishOperation>(); |
| |
| String serverTypeId = getServerType().getId(); |
| |
| IPublishTask[] publishTasks = ServerPlugin.getPublishTasks(); |
| if (publishTasks != null) { |
| List enabledTasks = getEnabledOptionalPublishOperationIds(); |
| List disabledTasks = getDisabledPreferredPublishOperationIds(); |
| |
| TaskModel taskModel = new TaskModel(); |
| taskModel.putObject(TaskModel.TASK_SERVER, this); |
| |
| int size = publishTasks.length; |
| for (int i = 0; i < size; i++) { |
| IPublishTask task = publishTasks[i]; |
| if (task.supportsType(serverTypeId)) { |
| PublishOperation[] tasks2 = task.getTasks(this, kind, moduleList, kindList); |
| if (tasks2 != null) { |
| int size2 = tasks2.length; |
| for (int j = 0; j < size2; j++) { |
| if (tasks2[j].getKind() == PublishOperation.REQUIRED) { |
| tasks.add(tasks2[j]); |
| tasks2[j].setTaskModel(taskModel); |
| } else if (tasks2[j].getKind() == PublishOperation.PREFERRED) { |
| String opId = getPublishOperationId(tasks2[j]); |
| if (!disabledTasks.contains(opId)) { |
| tasks.add(tasks2[j]); |
| tasks2[j].setTaskModel(taskModel); |
| } |
| } else if (tasks2[j].getKind() == PublishOperation.OPTIONAL) { |
| String opId = getPublishOperationId(tasks2[j]); |
| if (enabledTasks.contains(opId)) { |
| tasks.add(tasks2[j]); |
| tasks2[j].setTaskModel(taskModel); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| Collections.sort(tasks, PUBLISH_OPERATION_COMPARTOR); |
| |
| return tasks.toArray(new PublishOperation[tasks.size()]); |
| } |
| |
| /** |
| * Returns all the publishers that are available with this server, |
| * whether or not they are currently enabled. |
| * |
| * @return a possibly empty array of Publishers |
| */ |
| public Publisher[] getAllPublishers() { |
| List<Publisher> pubs = new ArrayList<Publisher>(); |
| |
| String serverTypeId = getServerType().getId(); |
| |
| TaskModel taskModel = new TaskModel(); |
| taskModel.putObject(TaskModel.TASK_SERVER, this); |
| |
| Publisher[] publishers = ServerPlugin.getPublishers(); |
| if (publishers != null) { |
| int size = publishers.length; |
| for (int i = 0; i < size; i++) { |
| Publisher pub = publishers[i]; |
| if (pub.supportsType(serverTypeId)) { |
| pub.setTaskModel(taskModel); |
| pubs.add(pub); |
| } |
| } |
| } |
| |
| return pubs.toArray(new Publisher[pubs.size()]); |
| } |
| |
| /** |
| * Returns the publishers that have been targeted to this server and |
| * are enabled. |
| * |
| * @return a possibly empty array of Publishers |
| */ |
| public Publisher[] getEnabledPublishers() { |
| List<Publisher> pubs = new ArrayList<Publisher>(); |
| |
| String serverTypeId = getServerType().getId(); |
| |
| TaskModel taskModel = new TaskModel(); |
| taskModel.putObject(TaskModel.TASK_SERVER, this); |
| |
| Publisher[] publishers = ServerPlugin.getPublishers(); |
| if (publishers != null) { |
| int size = publishers.length; |
| for (int i = 0; i < size; i++) { |
| Publisher pub = publishers[i]; |
| if (pub.supportsType(serverTypeId) && isPublisherEnabled(pub)) { |
| pub.setTaskModel(taskModel); |
| pubs.add(pub); |
| } |
| } |
| } |
| |
| return pubs.toArray(new Publisher[pubs.size()]); |
| } |
| |
| /** |
| * Returns all publish tasks that have been targeted to this server type. |
| * The tasks will not be initialized with a task model. |
| * |
| * @param moduleList a list of modules |
| * @return an array of publish operations |
| */ |
| public PublishOperation[] getAllTasks(List moduleList) { |
| String serverTypeId = getServerType().getId(); |
| if (serverTypeId == null) |
| return new PublishOperation[0]; |
| |
| List<PublishOperation> tasks = new ArrayList<PublishOperation>(); |
| |
| IPublishTask[] publishTasks = ServerPlugin.getPublishTasks(); |
| if (publishTasks != null) { |
| int size = publishTasks.length; |
| for (int i = 0; i < size; i++) { |
| IPublishTask task = publishTasks[i]; |
| if (task.supportsType(serverTypeId)) { |
| PublishOperation[] tasks2 = task.getTasks(this, moduleList); |
| tasks.addAll(Arrays.asList(tasks2)); |
| } |
| } |
| } |
| |
| Collections.sort(tasks, PUBLISH_OPERATION_COMPARTOR); |
| |
| return tasks.toArray(new PublishOperation[tasks.size()]); |
| } |
| |
| public String getPublishOperationId(PublishOperation op) { |
| return getId()+"|"+op.getLabel(); |
| } |
| |
| /** |
| * Returns a list containing module arrays of every module on the |
| * server. |
| * |
| * @return a list of IModule[] |
| */ |
| public List<IModule[]> getAllModules() { |
| final List<IModule[]> moduleList = new ArrayList<IModule[]>(); |
| |
| IModuleVisitor visitor = new IModuleVisitor() { |
| public boolean visit(IModule[] module) { |
| if (!moduleList.contains(module)) |
| moduleList.add(module); |
| return true; |
| } |
| }; |
| |
| visit(visitor, null); |
| |
| return moduleList; |
| } |
| |
| /* |
| * Returns the module resources that have been published. |
| * |
| * @see ServerBehaviourDelegate.getPublishedResources(IModule[]) |
| */ |
| public IModuleResource[] getResources(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| return getServerPublishInfo().getResources(module); |
| } |
| |
| /* |
| * Returns the module resources that have been published. |
| * |
| * @see ServerBehaviourDelegate.getPublishedResources(IModule[]) |
| */ |
| public IModuleResource[] getPublishedResources(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| return getServerPublishInfo().getModulePublishInfo(module).getResources(); |
| } |
| |
| /* |
| * Returns the delta of the current module resources that have been |
| * published compared to the current state of the module. |
| * |
| * @see ServerBehaviourDelegate.getPublishedResourceDelta(IModule[]) |
| */ |
| public IModuleResourceDelta[] getPublishedResourceDelta(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| return getServerPublishInfo().getDelta(module); |
| } |
| |
| /* |
| * Returns the delta of the current module resources that have been |
| * published compared to the current state of the module. |
| * |
| * @see ServerBehaviourDelegate.getPublishedResourceDelta(IModule[]) |
| */ |
| public boolean hasPublishedResourceDelta(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| return getServerPublishInfo().hasDelta(module); |
| } |
| |
| /** |
| * @see IServer#getAdapter(Class) |
| */ |
| public Object getAdapter(Class adapter) { |
| if (delegate != null) { |
| if (adapter.isInstance(delegate)) |
| return delegate; |
| } |
| if (behaviourDelegate != null) { |
| if (adapter.isInstance(behaviourDelegate)) |
| return behaviourDelegate; |
| } |
| return Platform.getAdapterManager().getAdapter(this, adapter); |
| } |
| |
| /** |
| * @see IServer#loadAdapter(Class, IProgressMonitor) |
| */ |
| public Object loadAdapter(Class adapter, IProgressMonitor monitor) { |
| getDelegate(monitor); |
| if (adapter.isInstance(delegate)) |
| return delegate; |
| |
| getBehaviourDelegate(monitor); |
| if (adapter.isInstance(behaviourDelegate)) |
| return behaviourDelegate; |
| |
| return Platform.getAdapterManager().loadAdapter(this, adapter.getName()); |
| } |
| |
| /** |
| * Returns true if the server is in a state that it can |
| * be started, and supports the given mode. |
| * |
| * @param mode2 |
| * @return status |
| */ |
| public IStatus canStart(String mode2) { |
| if (getServerType() == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null); |
| |
| int state = getServerState(); |
| if (state != STATE_STOPPED && state != STATE_UNKNOWN) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.canStartErrorState, null); |
| |
| if (!getServerType().supportsLaunchMode(mode2)) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorLaunchMode, null); |
| |
| if (getBehaviourDelegate(new NullProgressMonitor()) != null) |
| return getBehaviourDelegate(new NullProgressMonitor()).canStart(mode2); |
| |
| return Status.OK_STATUS; |
| } |
| |
| public ILaunch getLaunch() { |
| if (launch != null && !launch.isTerminated()) |
| return launch; |
| return null; |
| } |
| |
| public void setLaunch(ILaunch launch) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "setLaunch() " + launch); |
| } |
| this.launch = launch; |
| } |
| |
| public void setupLaunchConfiguration(ILaunchConfigurationWorkingCopy workingCopy, IProgressMonitor monitor) { |
| try { |
| getBehaviourDelegate(monitor).setupLaunchConfiguration(workingCopy, monitor); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error calling delegate setupLaunchConfiguration() " |
| + toString(), e); |
| } |
| } |
| } |
| |
| /** |
| * Return the launch configuration for this server. If one does not exist, it |
| * will be created if "create" is true, and otherwise will return <code>null</code>. |
| * Will return <code>null</code> if this server type has no associated launch |
| * configuration type (i.e. the server cannot be started). |
| * |
| * @param create <code>true</code> if a new launch configuration should be |
| * created if there are none already |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting and cancellation are not desired |
| * @return the launch configuration, or <code>null</code> if there was no |
| * existing launch configuration and <code>create</code> was false |
| * @throws CoreException |
| */ |
| public ILaunchConfiguration getLaunchConfiguration(boolean create, IProgressMonitor monitor) throws CoreException { |
| if (getServerType() == null) |
| return null; |
| |
| ILaunchConfigurationType launchConfigType = ((ServerType) getServerType()).getLaunchConfigurationType(); |
| if (launchConfigType == null) |
| return null; |
| |
| ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunchConfiguration[] launchConfigs = null; |
| try { |
| launchConfigs = launchManager.getLaunchConfigurations(launchConfigType); |
| } catch (CoreException e) { |
| // ignore |
| } |
| |
| if (launchConfigs != null) { |
| int size = launchConfigs.length; |
| for (int i = 0; i < size; i++) { |
| try { |
| String serverId = launchConfigs[i].getAttribute(SERVER_ID, (String) null); |
| if (getId().equals(serverId)) { |
| final ILaunchConfigurationWorkingCopy wc = launchConfigs[i].getWorkingCopy(); |
| setupLaunchConfiguration(wc, monitor); |
| if (wc.isDirty()) { |
| final ILaunchConfiguration[] lc = new ILaunchConfiguration[1]; |
| Job job = new Job("Saving launch configuration") { |
| protected IStatus run(IProgressMonitor monitor2) { |
| try { |
| lc[0] = wc.doSave(); |
| } catch (CoreException ce) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error configuring launch", |
| ce); |
| } |
| } |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setSystem(true); |
| job.schedule(); |
| try { |
| job.join(); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error configuring launch", e); |
| } |
| } |
| if (job.getState() != Job.NONE) { |
| job.cancel(); |
| lc[0] = wc.doSave(); |
| } |
| |
| return lc[0]; |
| } |
| return launchConfigs[i]; |
| } |
| } catch (CoreException e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error configuring launch", e); |
| } |
| } |
| } |
| } |
| |
| if (!create) |
| return null; |
| |
| // create a new launch configuration |
| String launchName = getValidLaunchConfigurationName(getName()); |
| launchName = launchManager.generateUniqueLaunchConfigurationNameFrom(launchName); |
| ILaunchConfigurationWorkingCopy wc = launchConfigType.newInstance(null, launchName); |
| wc.setAttribute(SERVER_ID, getId()); |
| setupLaunchConfiguration(wc, monitor); |
| return wc.doSave(); |
| } |
| |
| protected String getValidLaunchConfigurationName(String s) { |
| if (s == null || s.length() == 0) |
| return "1"; |
| int size = INVALID_CHARS.length; |
| for (int i = 0; i < size; i++) { |
| s = s.replace(INVALID_CHARS[i], '_'); |
| } |
| return s; |
| } |
| |
| /** |
| * Clean up any metadata associated with the server, typically in preparation for |
| * deletion. |
| */ |
| protected void deleteMetadata() { |
| deleteLaunchConfigurations(); |
| ServerPlugin.getInstance().removeTempDirectory(getId()); |
| PublishInfo.getInstance().removeServerPublishInfo(this); |
| } |
| |
| /** |
| * Clean up any old launch configurations with the current server's id. |
| */ |
| protected void deleteLaunchConfigurations() { |
| if (getServerType() == null) |
| return; |
| |
| ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunchConfigurationType launchConfigType = ((ServerType) getServerType()).getLaunchConfigurationType(); |
| |
| ILaunchConfiguration[] configs = null; |
| try { |
| configs = launchManager.getLaunchConfigurations(launchConfigType); |
| int size = configs.length; |
| for (int i = 0; i < size; i++) { |
| try { |
| if (getId().equals(configs[i].getAttribute(SERVER_ID, (String) null))) |
| configs[i].delete(); |
| } catch (Exception e) { |
| // ignore |
| } |
| } |
| } catch (Exception e) { |
| // ignore |
| } |
| } |
| |
| /** |
| * @see IServer#canRestart(String) |
| */ |
| public IStatus canRestart(String mode2) { |
| if (getServerType() == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null); |
| |
| if (!getServerType().supportsLaunchMode(mode2)) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorLaunchMode, null); |
| |
| if (getServerState() != STATE_STARTED) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorRestartNotStarted, null); |
| |
| if (getBehaviourDelegate(new NullProgressMonitor()) != null) |
| return getBehaviourDelegate(new NullProgressMonitor()).canRestart(mode2); |
| |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Returns the current restart state of the server. This |
| * implementation will always return false when the server |
| * is stopped. |
| * |
| * @return boolean |
| */ |
| public boolean getServerRestartState() { |
| if (getServerState() == STATE_STOPPED) |
| return false; |
| return serverRestartNeeded; |
| } |
| |
| /** |
| * Sets the server restart state. |
| * |
| * @param state boolean |
| */ |
| public synchronized void setServerRestartState(boolean state) { |
| if (state == serverRestartNeeded) |
| return; |
| serverRestartNeeded = state; |
| fireRestartStateChangeEvent(); |
| } |
| |
| /** |
| * @see IServer#restart(String, IProgressMonitor) |
| */ |
| public void restart(final String mode2, final IProgressMonitor monitor) { |
| if (getServerType() == null || getServerState() == STATE_STOPPED) |
| return; |
| |
| if (getServerType() == null) |
| return; |
| |
| if (getServerState() == STATE_STOPPED) |
| return; |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Restarting server: " + getName()); |
| } |
| |
| RestartJob restartJob = new RestartJob(mode2); |
| restartJob.schedule(); |
| } |
| |
| /** |
| * Returns true if the server is in a state that it can |
| * be stopped. |
| * |
| * @return boolean |
| */ |
| public IStatus canStop() { |
| if (getServerType() == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null); |
| |
| if (getServerState() == STATE_STOPPED || getServerState() == STATE_STOPPING) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorStopAlreadyStopped, null); |
| |
| if (!getServerType().supportsLaunchMode(getMode())) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorLaunchMode, null); |
| |
| if (getBehaviourDelegate(new NullProgressMonitor()) != null) |
| return getBehaviourDelegate(new NullProgressMonitor()).canStop(); |
| |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * @see IServer#stop(boolean) |
| */ |
| public void stop(boolean force) { |
| if (getServerState() == STATE_STOPPED) |
| return; |
| |
| StopJob job = new StopJob(force); |
| job.schedule(); |
| } |
| |
| protected IStatus publishBeforeStart(IProgressMonitor monitor, boolean synchronous){ |
| |
| // check if we need to publish |
| byte pub = StartJob.PUBLISH_NONE; |
| if (ServerCore.isAutoPublishing() && shouldPublish()) { |
| if (((ServerType)getServerType()).startBeforePublish()) |
| return Status.OK_STATUS; |
| pub = StartJob.PUBLISH_BEFORE; |
| } |
| |
| final IStatus [] pubStatus = new IStatus[]{Status.OK_STATUS}; |
| |
| // publish before start |
| byte publish = pub; |
| if (publish == StartJob.PUBLISH_BEFORE) { |
| PublishJob pubJob = new PublishJob(IServer.PUBLISH_INCREMENTAL, null,false, null); |
| pubJob.addJobChangeListener(new JobChangeAdapter(){ |
| public void done(IJobChangeEvent event) { |
| IStatus status = event.getResult(); |
| if (status != null && status.getSeverity() == IStatus.ERROR) |
| pubStatus[0] = status; |
| } |
| |
| }); |
| |
| pubJob.schedule(); |
| |
| try{ |
| if (synchronous) |
| pubJob.join(); |
| |
| } |
| catch (InterruptedException ie){ |
| return Status.CANCEL_STATUS; |
| } |
| } |
| return pubStatus[0]; |
| } |
| |
| protected IStatus publishAfterStart(IProgressMonitor monitor, boolean synchronous, final IOperationListener op){ |
| |
| // check if we need to publish |
| byte pub = StartJob.PUBLISH_NONE; |
| if (ServerCore.isAutoPublishing() && shouldPublish()) { |
| if (((ServerType)getServerType()).startBeforePublish()) |
| pub = StartJob.PUBLISH_AFTER; |
| else { |
| if(op != null) { |
| op.done(Status.OK_STATUS); |
| } |
| return Status.OK_STATUS; |
| } |
| } |
| |
| final IStatus [] pubStatus = new IStatus[]{Status.OK_STATUS}; |
| |
| // publish after start |
| byte publish = pub; |
| if (publish == StartJob.PUBLISH_AFTER) { |
| PublishJob pubJob = new PublishJob(IServer.PUBLISH_INCREMENTAL, null,false, null); |
| pubJob.addJobChangeListener(new JobChangeAdapter(){ |
| public void done(IJobChangeEvent event) { |
| IStatus status = event.getResult(); |
| if (status != null && status.getSeverity() == IStatus.ERROR) |
| pubStatus[0] = status; |
| if (op != null){ |
| op.done(status); |
| } |
| } |
| |
| }); |
| |
| pubJob.schedule(); |
| |
| try{ |
| if (synchronous) |
| pubJob.join(); |
| } |
| catch (InterruptedException ie){ |
| return Status.CANCEL_STATUS; |
| } |
| } |
| return pubStatus[0]; |
| } |
| |
| /** |
| * @see IServer#start(String, IProgressMonitor) |
| */ |
| public void start(String mode2, IProgressMonitor monitor) throws CoreException { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Starting server: " + toString() + ", launchMode: " + mode2); |
| } |
| if (getServerType() == null) |
| return; |
| |
| // make sure that the delegate is loaded and the server state is correct |
| loadAdapter(ServerBehaviourDelegate.class, null); |
| |
| IStatus status = publishBeforeStart(monitor,false); |
| |
| if (status != null && status.getSeverity() == IStatus.ERROR){ |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine"); |
| } |
| return; |
| } |
| |
| StartJob startJob = new StartJob(mode2); |
| // 287442 - only do publish after start if the server start is successful. |
| final IProgressMonitor monitor2 = monitor; |
| startJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| IStatus resultStatus = event.getResult(); |
| if (resultStatus != null && resultStatus.getSeverity() == IStatus.ERROR) { |
| if (Trace.INFO) { |
| Trace.trace(Trace.STRING_INFO, |
| "Skipping auto publish after server start since the server start failed."); |
| } |
| } else { |
| publishAfterStart(monitor2,false,null); |
| } |
| } |
| }); |
| startJob.schedule(); |
| } |
| |
| /** |
| * @see IServer#start(String, IOperationListener) |
| */ |
| public void start(String mode2, final IOperationListener opListener) { |
| if (getServerType() == null) { |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| return; |
| } |
| |
| // make sure that the delegate is loaded and the server state is correct |
| loadAdapter(ServerBehaviourDelegate.class, null); |
| |
| IStatus status = publishBeforeStart(null,false); |
| |
| if (status != null && status.getSeverity() == IStatus.ERROR){ |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine"); |
| } |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| return; |
| } |
| |
| // check the publish flag (again) to determine when to call opListener.done |
| byte pub = StartJob.PUBLISH_NONE; |
| if (ServerCore.isAutoPublishing() && shouldPublish()) { |
| if (((ServerType)getServerType()).startBeforePublish()) |
| pub = StartJob.PUBLISH_AFTER; |
| else |
| pub = StartJob.PUBLISH_BEFORE; |
| } |
| |
| if (ServerPlugin.isRunningGUIMode()){ |
| ServerPlugin.getSaveEditorHelper().saveAllEditors(); |
| } |
| |
| StartJob startJob = new StartJob(mode2); |
| if (opListener != null && pub != StartJob.PUBLISH_AFTER) { |
| startJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| // 287442 - only do publish after start if the server start is successful. |
| if (pub == StartJob.PUBLISH_AFTER) { |
| startJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| IStatus resultStatus = event.getResult(); |
| if (resultStatus != null && resultStatus.getSeverity() == IStatus.ERROR) { |
| if (Trace.INFO) { |
| Trace.trace(Trace.STRING_INFO, |
| "Skipping auto publish after server start since the server start failed."); |
| } |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| } |
| else { |
| publishAfterStart(null,false,opListener); |
| } |
| } |
| }); |
| } |
| startJob.schedule(); |
| } |
| |
| public void synchronousStart(String mode2, IProgressMonitor monitor) throws CoreException { |
| if (getServerType() == null) |
| return; |
| |
| // make sure that the delegate is loaded and the server state is correct |
| loadAdapter(ServerBehaviourDelegate.class, monitor); |
| |
| IStatus status = publishBeforeStart(monitor,true); |
| |
| if (status != null && status.getSeverity() == IStatus.ERROR){ |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine"); |
| } |
| return; |
| } |
| |
| StartJob startJob = new StartJob(mode2); |
| // 287442 - only do publish after start if the server start is successful. |
| final IProgressMonitor monitor2 = monitor; |
| startJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| IStatus resultStatus = event.getResult(); |
| if (resultStatus != null && resultStatus.getSeverity() == IStatus.ERROR) { |
| if (Trace.INFO) { |
| Trace.trace(Trace.STRING_INFO, |
| "Skipping auto publish after server start since the server start failed."); |
| } |
| } else { |
| publishAfterStart(monitor2,true,null); |
| } |
| } |
| }); |
| startJob.schedule(); |
| |
| try { |
| startJob.join(); |
| } catch (InterruptedException e) { |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e); |
| } |
| } |
| } |
| |
| /* |
| * @see IServer#synchronousRestart(String, IProgressMonitor) |
| */ |
| public void synchronousRestart(String mode2, IProgressMonitor monitor) throws CoreException { |
| synchronousStop(true); |
| synchronousStart(mode2, monitor); |
| } |
| |
| /* |
| * @see IServer#restart(String, IOperationListener) |
| */ |
| public void restart(String mode2, final IOperationListener opListener) { |
| if (getServerType() == null) { |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| return; |
| } |
| |
| if (getServerState() == STATE_STOPPED) { |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| return; |
| } |
| |
| RestartJob restartJob = new RestartJob(mode2); |
| if (opListener != null) { |
| restartJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| restartJob.schedule(); |
| } |
| |
| /* |
| * @see IServer#stop(boolean, IOperationListener) |
| */ |
| public void stop(boolean force, final IOperationListener opListener) { |
| if (getServerType() == null) { |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| return; |
| } |
| |
| if (getServerState() == IServer.STATE_STOPPED) { |
| if (opListener != null) |
| opListener.done(Status.OK_STATUS); |
| return; |
| } |
| |
| StopJob job = new StopJob(force); |
| if (opListener != null) { |
| job.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| job.schedule(); |
| } |
| |
| /* |
| * @see IServer#synchronousStop() |
| */ |
| public void synchronousStop(boolean force) { |
| if (getServerType() == null) |
| return; |
| |
| if (getServerState() == IServer.STATE_STOPPED) |
| return; |
| |
| StopJob job = new StopJob(force); |
| job.schedule(); |
| try { |
| job.join(); |
| } catch (InterruptedException e) { |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e); |
| } |
| } |
| } |
| |
| /* |
| * Trigger a restart of the given module and wait until it has finished restarting. |
| * |
| * @param module org.eclipse.wst.server.core.IModule |
| * @param monitor org.eclipse.core.runtime.IProgressMonitor |
| * @exception org.eclipse.core.runtime.CoreException - thrown if an error occurs while trying to restart the module |
| * |
| public void synchronousRestartModule(final IModule[] module, IProgressMonitor monitor) throws CoreException { |
| Trace.trace(Trace.FINEST, "synchronousModuleRestart 1"); |
| |
| final Object mutex = new Object(); |
| |
| // add listener to the module |
| IServerListener listener = new IServerListener() { |
| public void serverChanged(ServerEvent event) { |
| int eventKind = event.getKind(); |
| IServer server = event.getServer(); |
| if (eventKind == (ServerEvent.MODULE_CHANGE | ServerEvent.STATE_CHANGE)) { |
| int state = server.getModuleState(module); |
| if (state == IServer.STATE_STARTED || state == IServer.STATE_STOPPED) { |
| // notify waiter |
| synchronized (mutex) { |
| try { |
| Trace.trace(Trace.FINEST, "synchronousModuleRestart notify"); |
| mutex.notifyAll(); |
| } catch (Exception e) { |
| Trace.trace(Trace.SEVERE, "Error notifying module restart", e); |
| } |
| } |
| } |
| } |
| } |
| }; |
| addServerListener(listener); |
| |
| // make sure it times out after 30s |
| class Timer { |
| boolean timeout; |
| boolean alreadyDone; |
| } |
| final Timer timer = new Timer(); |
| |
| Thread thread = new Thread() { |
| public void run() { |
| try { |
| Thread.sleep(30000); |
| if (!timer.alreadyDone) { |
| timer.timeout = true; |
| // notify waiter |
| synchronized (mutex) { |
| Trace.trace(Trace.FINEST, "synchronousModuleRestart notify timeout"); |
| mutex.notifyAll(); |
| } |
| } |
| } catch (Exception e) { |
| Trace.trace(Trace.SEVERE, "Error notifying module restart timeout", e); |
| } |
| } |
| }; |
| thread.setDaemon(true); |
| thread.start(); |
| |
| Trace.trace(Trace.FINEST, "synchronousModuleRestart 2"); |
| |
| // restart the module |
| try { |
| getBehaviourDelegate(null).restartModule(module, monitor); |
| } catch (CoreException e) { |
| removeServerListener(listener); |
| throw e; |
| } |
| |
| Trace.trace(Trace.FINEST, "synchronousModuleRestart 3"); |
| |
| // wait for it! wait for it! ... |
| synchronized (mutex) { |
| try { |
| while (!timer.timeout && !(getModuleState(module) == IServer.STATE_STARTED || getModuleState(module) == IServer.STATE_STOPPED)) |
| mutex.wait(); |
| } catch (Exception e) { |
| Trace.trace(Trace.SEVERE, "Error waiting for server start", e); |
| } |
| } |
| removeServerListener(listener); |
| if (timer.timeout) |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorModuleRestartFailed, getName()), null)); |
| timer.alreadyDone = true; |
| |
| if (getModuleState(module) == IServer.STATE_STOPPED) |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorModuleRestartFailed, getName()), null)); |
| |
| Trace.trace(Trace.FINEST, "synchronousModuleRestart 4"); |
| }*/ |
| |
| public IPath getTempDirectory() { |
| return ServerPlugin.getInstance().getTempDirectory(getId()); |
| } |
| |
| public IPath getTempDirectory(boolean recycle) { |
| return ServerPlugin.getInstance().getTempDirectory(getId(), recycle); |
| } |
| |
| protected String getXMLRoot() { |
| return "server"; |
| } |
| |
| protected void loadState(IMemento memento) { |
| resolve(); |
| } |
| |
| public void serialize(IMemento memento) { |
| save(memento); |
| } |
| |
| public void deserialize(IMemento memento) { |
| load(memento); |
| } |
| |
| protected void resolve() { |
| IServerType oldServerType = serverType; |
| String serverTypeId = getAttribute("server-type-id", (String)null); |
| if (serverTypeId != null) |
| serverType = ServerCore.findServerType(serverTypeId); |
| else |
| serverType = null; |
| if (serverType != null && !serverType.equals(oldServerType)) |
| serverState = ((ServerType)serverType).getInitialState(); |
| |
| String runtimeId = getAttribute(RUNTIME_ID, (String)null); |
| if (runtimeId != null) |
| runtime = ServerCore.findRuntime(runtimeId); |
| |
| String configPath = getAttribute(CONFIGURATION_ID, (String)null); |
| configuration = null; |
| if (configPath != null) |
| configuration = ResourcesPlugin.getWorkspace().getRoot().getFolder(new Path(configPath)); |
| |
| // for migration from WTP 2.0 -> WTP 3.0 |
| int autoPubSetting = getAttribute(PROP_AUTO_PUBLISH_SETTING, AUTO_PUBLISH_RESOURCE); |
| if (autoPubSetting == 0) |
| map.put(PROP_AUTO_PUBLISH_SETTING, AUTO_PUBLISH_RESOURCE); |
| } |
| |
| protected void setInternal(ServerWorkingCopy wc) { |
| map = new HashMap<String, Object>(wc.map); |
| configuration = wc.configuration; |
| runtime = wc.runtime; |
| serverSyncState = wc.serverSyncState; |
| //restartNeeded = wc.restartNeeded; |
| serverType = wc.serverType; |
| synchronized(modulesLock){ |
| modules = wc.modules; |
| } |
| |
| // can never modify the following properties via the working copy |
| //serverState = wc.serverState; |
| delegate = wc.delegate; |
| |
| } |
| |
| protected void saveState(IMemento memento) { |
| if (serverType != null) |
| memento.putString("server-type", serverType.getId()); |
| |
| if (configuration != null) |
| memento.putString(CONFIGURATION_ID, configuration.getFullPath().toString()); |
| else |
| memento.putString(CONFIGURATION_ID, null); |
| |
| if (runtime != null) |
| memento.putString(RUNTIME_ID, runtime.getId()); |
| else |
| memento.putString(RUNTIME_ID, null); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServer#canModifyModule(org.eclipse.wst.server.core.model.IModule) |
| */ |
| public IStatus canModifyModules(IModule[] add, IModule[] remove, IProgressMonitor monitor) { |
| if ((add == null || add.length == 0) && (remove == null || remove.length == 0)) |
| throw new IllegalArgumentException("Add and remove cannot both be null/empty"); |
| |
| if (add != null) { |
| int size = add.length; |
| for (int i = 0; i < size; i++) |
| if (add[i] == null) |
| throw new IllegalArgumentException("Cannot add null entries"); |
| } |
| |
| if (remove != null) { |
| int size = remove.length; |
| for (int i = 0; i < size; i++) |
| if (remove[i] == null) |
| throw new IllegalArgumentException("Cannot remove null entries"); |
| } |
| |
| if (getServerType() == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorMissingAdapter, null); |
| |
| if (add != null && add.length > 0) { |
| int size = add.length; |
| for (int i = 0; i < size; i++) { |
| IModuleType moduleType = add[i].getModuleType(); |
| if (!ServerUtil.isSupportedModule(getServerType().getRuntimeType().getModuleTypes(), moduleType)) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCannotAddModule, |
| new Object[] { moduleType.getName(), moduleType.getVersion() }), null); |
| } |
| } |
| |
| try { |
| return getDelegate(monitor).canModifyModules(add, remove); |
| } catch (Exception e) { |
| ServerPlugin.logExtensionFailure(toString(), e); |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, e.getMessage(), e); |
| } |
| } |
| |
| public void clearModuleCache() { |
| synchronized (modulesLock){ |
| modules = null; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServer#getModules() |
| */ |
| public IModule[] getModules() { |
| synchronized (modulesLock){ |
| return getModulesWithoutLock(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * The implementation for getModules but this one does not lock the modules object. Caller is responsible for locking the modulesLock |
| * object when calling this method for thread safe implementation. |
| * @see org.eclipse.wst.server.core.IServer#getModules() |
| */ |
| protected IModule[] getModulesWithoutLock() { |
| if (modules == null) { |
| // convert from attribute |
| List<String> list = getAttribute(MODULE_LIST, (List<String>) null); |
| if (list == null) |
| list = new ArrayList<String>(1); |
| |
| modules = new ArrayList<IModule>(list.size() + 1); |
| Iterator iterator = list.iterator(); |
| while (iterator.hasNext()) { |
| String moduleId = (String) iterator.next(); |
| String name = "<unknown>"; |
| int index = moduleId.indexOf("::"); |
| if (index > 0) { |
| name = moduleId.substring(0, index); |
| moduleId = moduleId.substring(index+2); |
| } |
| |
| String moduleTypeId = null; |
| String moduleTypeVersion = null; |
| index = moduleId.indexOf("::"); |
| if (index > 0) { |
| int index2 = moduleId.indexOf("::", index+1); |
| moduleTypeId = moduleId.substring(index+2, index2); |
| moduleTypeVersion = moduleId.substring(index2+2); |
| moduleId = moduleId.substring(0, index); |
| } |
| |
| IModule module = ServerUtil.getModule(moduleId); |
| if (module == null) { |
| IModuleType moduleType = null; |
| if (moduleTypeId != null) |
| moduleType = ModuleType.getModuleType(moduleTypeId, moduleTypeVersion); |
| module = new DeletedModule(moduleId, name, moduleType); |
| } |
| modules.add(module); |
| } |
| } |
| |
| List em = getExternalModules(); |
| if (em == null || em.isEmpty()) { |
| IModule[] modules2 = new IModule[modules.size()]; |
| modules.toArray(modules2); |
| return modules2; |
| } |
| |
| IModule[] modules2 = new IModule[modules.size() + em.size()]; |
| modules.toArray(modules2); |
| |
| Object[] obj = em.toArray(); |
| System.arraycopy(obj, 0, modules2, modules.size(), em.size()); |
| |
| return modules2; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServer#getModuleState() |
| */ |
| public int getModuleState(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| Integer in = moduleState.get(getKey(module)); |
| if (in != null) |
| return in.intValue(); |
| } catch (Exception e) { |
| // ignore |
| } |
| return STATE_UNKNOWN; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServer#getModuleState() |
| */ |
| public int getModulePublishState(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| Integer in = modulePublishState.get(getKey(module)); |
| if (in != null) |
| return in.intValue(); |
| } catch (Exception e) { |
| // ignore |
| } |
| return PUBLISH_STATE_UNKNOWN; |
| } |
| |
| /* |
| * @see IServer#getChildModule(IModule[]) |
| */ |
| public IModule[] getChildModules(IModule[] module, IProgressMonitor monitor) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| int i = module.length - 1; |
| if (!module[i].isExternal() && (module[i].getProject() == null || !module[i].getProject().isAccessible())) |
| return null; |
| |
| ServerDelegate sd = getDelegate(monitor); |
| if (sd == null) |
| return null; |
| IModule[] children = sd.getChildModules(module); |
| if (children != null && children.length == 1 && children[0].equals(module[module.length - 1])) |
| return null; |
| return children; |
| } catch (Exception e) { |
| ServerPlugin.logExtensionFailure(toString(), e); |
| return null; |
| } |
| } |
| |
| /* |
| * @see IServer#getRootModules(IModule) |
| */ |
| public IModule[] getRootModules(IModule module, IProgressMonitor monitor) throws CoreException { |
| if (module == null) |
| throw new IllegalArgumentException("Module cannot be null"); |
| try { |
| return getDelegate(monitor).getRootModules(module); |
| } catch (CoreException se) { |
| throw se; |
| } catch (Exception e) { |
| ServerPlugin.logExtensionFailure(toString(), e); |
| return null; |
| } |
| } |
| |
| /** |
| * Returns whether the given module can be restarted. |
| * |
| * @param module the module |
| * @param monitor |
| * @return <code>true</code> if the given module can be |
| * restarted, and <code>false</code> otherwise |
| * @deprecated use canRestartModule or canPublishModule |
| */ |
| public IStatus canControlModule(IModule[] module, IProgressMonitor monitor) { |
| return canRestartModule(module,monitor); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServer#canRestartModule(org.eclipse.wst.server.core.IModule[], org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public IStatus canRestartModule(IModule[] module, IProgressMonitor monitor) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| ServerBehaviourDelegate bd = getBehaviourDelegate(monitor); |
| if (bd == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorRestartModule, null); |
| boolean b = bd.canRestartModule(module); |
| if (b) |
| return Status.OK_STATUS; |
| } catch (Exception e) { |
| ServerPlugin.logExtensionFailure(toString(), e); |
| } |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorRestartModule, null); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.server.core.IServer#canPublishModule(org.eclipse.wst.server.core.IModule[], org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public IStatus canPublishModule(IModule[] module, IProgressMonitor monitor) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| ServerBehaviourDelegate bd = getBehaviourDelegate(monitor); |
| if (bd == null) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishModule, null); |
| boolean b = bd.canPublishModule(module); |
| if (b) |
| return Status.OK_STATUS; |
| } catch (Exception e) { |
| ServerPlugin.logExtensionFailure(toString(), e); |
| } |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishModule, null); |
| } |
| |
| /** |
| * Check if the given module is in sync on the server. It should |
| * return true if the module should be restarted (is out of |
| * sync) or false if the module does not need to be restarted. |
| * |
| * @param module org.eclipse.wst.server.core.model.IModule |
| * @return boolean |
| */ |
| public boolean getModuleRestartState(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| Boolean b = moduleRestartState.get(getKey(module)); |
| if (b != null) |
| return b.booleanValue(); |
| } catch (Exception e) { |
| // ignore |
| } |
| return false; |
| } |
| |
| abstract class OperationContext { |
| public abstract void run(IProgressMonitor monitor) throws CoreException; |
| public void cancel() { |
| // do nothing |
| } |
| public abstract String getTimeoutMessage(); |
| public abstract String getFailureMessage(); |
| } |
| /** |
| * |
| * @param module the module that the operation applies to, or null for a server operation |
| * @param monitor cannot be null |
| * @return the status |
| */ |
| protected IStatus runAndWait(final IModule[] module, OperationContext runnable, final int operationTimeout, IProgressMonitor monitor) { |
| final boolean[] notified = new boolean[1]; |
| IServerListener listener = new IServerListener() { |
| public void serverChanged(ServerEvent event) { |
| int eventKind = event.getKind(); |
| if ((eventKind | ServerEvent.STATE_CHANGE) != 0) { |
| if ((module == null && (eventKind | ServerEvent.SERVER_CHANGE) != 0) || |
| (module != null && module.equals(event.getModule()) && (eventKind | ServerEvent.MODULE_CHANGE) != 0)) { |
| int state = getServerState(); |
| if (state == IServer.STATE_STARTED || state == IServer.STATE_STOPPED) { |
| // notify waiter |
| synchronized (notified) { |
| try { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "runAndWait notify"); |
| } |
| notified[0] = true; |
| notified.notifyAll(); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying runAndWait", e); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| }; |
| |
| class Timer { |
| boolean timeout; |
| boolean alreadyDone; |
| } |
| final Timer timer = new Timer(); |
| |
| final IProgressMonitor monitor2 = monitor; |
| Thread thread = new Thread("Server RunAndWait Timeout") { |
| public void run() { |
| try { |
| int totalTimeout = operationTimeout; |
| if (totalTimeout < 0) |
| totalTimeout = 1; |
| boolean userCancelled = false; |
| int retryPeriod = 1; |
| while (!notified[0] && totalTimeout > 0 && !userCancelled && !timer.alreadyDone) { |
| // The operationTimeout is in seconds. Therefore, each retry period have to wait for 1 sec. |
| Thread.sleep(retryPeriod * 1000); |
| if (operationTimeout > 0) |
| totalTimeout -= retryPeriod; |
| if (!notified[0] && !timer.alreadyDone && monitor2.isCanceled()) { |
| // user canceled |
| userCancelled = true; |
| if (launch != null && !launch.isTerminated()) |
| launch.terminate();//TODO |
| // notify waiter |
| synchronized (notified) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "runAndWait user cancelled"); |
| } |
| notified[0] = true; |
| notified.notifyAll(); |
| } |
| } |
| } |
| if (!userCancelled && !timer.alreadyDone && !notified[0]) { |
| // notify waiter |
| synchronized (notified) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "runAndWait notify timeout"); |
| } |
| if (!timer.alreadyDone && totalTimeout <= 0) |
| timer.timeout = true; |
| notified[0] = true; |
| notified.notifyAll(); |
| } |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying runAndWait timeout", e); |
| } |
| } |
| } |
| }; |
| thread.setDaemon(true); |
| thread.start(); |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "runAndWait 2"); |
| } |
| |
| // do the operation |
| try { |
| runnable.run(monitor); |
| } catch (CoreException e) { |
| removeServerListener(listener); |
| timer.alreadyDone = true; |
| return e.getStatus(); |
| } |
| if (monitor.isCanceled()) { |
| removeServerListener(listener); |
| timer.alreadyDone = true; |
| return Status.CANCEL_STATUS; |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "runAndWait 3"); |
| } |
| |
| // wait for it! wait for it! ... |
| synchronized (notified) { |
| try { |
| while (!notified[0] && !monitor.isCanceled() && !timer.timeout |
| && !(getServerState() == IServer.STATE_STARTED || getServerState() == IServer.STATE_STOPPED)) { |
| notified.wait(); |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error waiting for operation", e); |
| } |
| } |
| timer.alreadyDone = true; |
| } |
| removeServerListener(listener); |
| |
| if (timer.timeout) { |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 1, NLS.bind(Messages.errorStartTimeout, new String[] { getName(), (operationTimeout / 1000) + "" }), null); |
| } |
| |
| if (!monitor.isCanceled() && getServerState() == IServer.STATE_STOPPED) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 2, NLS.bind(Messages.errorStartFailed, getName()), null); |
| |
| return Status.OK_STATUS; |
| } |
| |
| /* |
| * @see IServer#startModule(IModule[], IOperationListener) |
| */ |
| public void startModule(final IModule[] module, final IOperationListener opListener) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty or empty"); |
| |
| Job moduleJob = new ServerJob(NLS.bind(Messages.jobStarting, module[0].getName())) { |
| protected IStatus run(IProgressMonitor monitor) { |
| return runAndWait(module, new OperationContext() { |
| public String getFailureMessage() { |
| return Messages.errorStartFailed; |
| } |
| |
| public String getTimeoutMessage() { |
| return Messages.errorStartTimeout; |
| } |
| |
| public void run(IProgressMonitor monitor2) throws CoreException { |
| try { |
| getBehaviourDelegate(monitor2).startModule(module, monitor2); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error calling delegate startModule() " |
| + toString(), e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, e.getMessage())); |
| } |
| } |
| }, getStartTimeout(), monitor); |
| } |
| }; |
| if (opListener != null) { |
| moduleJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| moduleJob.schedule(); |
| } |
| |
| /* |
| * @see IServer#stopModule(IModule[], IOperationListener) |
| */ |
| public void stopModule(final IModule[] module, final IOperationListener opListener) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| |
| Job moduleJob = new ServerJob(NLS.bind(Messages.jobStopping, module[0].getName())) { |
| protected IStatus run(IProgressMonitor monitor) { |
| return runAndWait(module, new OperationContext() { |
| public String getFailureMessage() { |
| return Messages.errorStopFailed; |
| } |
| |
| public String getTimeoutMessage() { |
| return Messages.errorStopFailed; |
| } |
| |
| public void run(IProgressMonitor monitor2) throws CoreException { |
| try { |
| getBehaviourDelegate(monitor2).stopModule(module, monitor2); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error calling delegate stopModule() " |
| + toString(), e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, e.getMessage())); |
| } |
| } |
| }, getStopTimeout(), monitor); |
| } |
| }; |
| if (opListener != null) { |
| moduleJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| moduleJob.schedule(); |
| } |
| |
| /* |
| * @see IServer#restartModule(IModule[], IOperationListener, IProgressMonitor) |
| */ |
| public void restartModule(final IModule[] module, final IOperationListener opListener) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| |
| Job moduleJob = new ServerJob(NLS.bind(Messages.jobRestarting, module[0].getName())) { |
| protected IStatus run(IProgressMonitor monitor) { |
| return runAndWait(module, new OperationContext() { |
| public String getFailureMessage() { |
| return Messages.errorRestartFailed; |
| } |
| |
| public String getTimeoutMessage() { |
| return Messages.errorRestartTimeout; |
| } |
| |
| public void run(IProgressMonitor monitor2) throws CoreException { |
| try { |
| getBehaviourDelegate(monitor2).restartModule(module, monitor2); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error calling delegate restartModule() " |
| + toString(), e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, e.getMessage())); |
| } |
| } |
| }, getStopTimeout() + getStartTimeout(), monitor); |
| } |
| }; |
| if (opListener != null) { |
| moduleJob.addJobChangeListener(new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| opListener.done(event.getResult()); |
| } |
| }); |
| } |
| moduleJob.schedule(); |
| } |
| |
| /** |
| * Returns an array of IServerPorts that this server has. |
| * |
| * @param monitor |
| * @return a possibly empty array of servers ports |
| */ |
| public ServerPort[] getServerPorts(IProgressMonitor monitor) { |
| try { |
| return getDelegate(monitor).getServerPorts(); |
| } catch (Exception e) { |
| ServerPlugin.logExtensionFailure(toString(), e); |
| return null; |
| } |
| } |
| |
| /** |
| * Visit all the modules in the server with the given module visitor. |
| * |
| * @param visitor the visitor |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting and cancellation are not desired |
| */ |
| public void visit(IModuleVisitor visitor, IProgressMonitor monitor) { |
| if (visitor == null) |
| throw new IllegalArgumentException("Visitor cannot be null"); |
| |
| IModule[] modules2 = getModules(); |
| if (modules2 != null) { |
| int size = modules2.length; |
| for (int i = 0; i < size; i++) { |
| if (!visitModule(new IModule[] { modules2[i] }, visitor, monitor)) |
| return; |
| } |
| } |
| } |
| |
| /** |
| * Returns true to keep visiting, and false to stop. |
| * |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting and cancellation are not desired |
| */ |
| private boolean visitModule(IModule[] module, IModuleVisitor visitor, IProgressMonitor monitor) { |
| if (module == null) |
| return true; |
| |
| if (!visitor.visit(module)) |
| return false; |
| |
| IModule[] children = getChildModules(module, monitor); |
| if (children != null) { |
| int size = children.length; |
| for (int i = 0; i < size; i++) { |
| IModule[] module2 = new IModule[module.length + 1]; |
| System.arraycopy(module, 0, module2, 0, module.length); |
| module2[module.length] = children[i]; |
| |
| if (!visitModule(module2, visitor, monitor)) |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| protected String getKey(IModule[] module) { |
| StringBuffer sb = new StringBuffer(); |
| |
| if (module != null) { |
| int size = module.length; |
| for (int i = 0; i < size; i++) { |
| if (i != 0) |
| sb.append("#"); |
| sb.append(module[i].getId()); |
| } |
| } |
| |
| return sb.toString(); |
| } |
| |
| public void setModuleStatus(IModule[] module, IStatus status) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| moduleStatus.put(getKey(module), status); |
| fireModuleStatusChangeEvent(module); |
| } |
| |
| public IStatus getModuleStatus(IModule[] module) { |
| if (module == null || module.length == 0) |
| throw new IllegalArgumentException("Module cannot be null or empty"); |
| try { |
| return moduleStatus.get(getKey(module)); |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| public void setServerStatus(IStatus status) { |
| serverStatus = status; |
| fireServerStatusChangeEvent(); |
| } |
| |
| public IStatus getServerStatus() { |
| return serverStatus; |
| } |
| |
| /** |
| * Switch the server's location between the workspace and .metadata. |
| * |
| * @param server a server |
| * @param monitor a progress monitor |
| * @throws CoreException if something goes wrong |
| */ |
| public static void switchLocation(Server server, IProgressMonitor monitor) throws CoreException { |
| IFile file = server.getFile(); |
| ServerWorkingCopy wc = (ServerWorkingCopy) server.createWorkingCopy(); |
| server.delete(); |
| if (file == null) { |
| IProject project = ServerType.getServerProject(); |
| file = ServerUtil.getUnusedServerFile(project, wc); |
| wc.setFile(file); |
| server.file = file; |
| } else { |
| wc.setFile(null); |
| server.file = null; |
| } |
| wc.save(true, monitor); |
| } |
| |
| /** |
| * Returns the current state of the server (see SERVER_XXX constants) after |
| * refreshing the state of the server. The only difference between this method |
| * and the method without a progress monitor is that this method may cause |
| * plugin loading and not return immediately. However, the server will always |
| * be updated and in sync, so the IServer.STATE_UNKNOWN state should never be |
| * returned. |
| * |
| * @param monitor |
| * @return the server state |
| */ |
| public int getServerState(IProgressMonitor monitor) { |
| loadAdapter(ServerBehaviourDelegate.class, monitor); |
| return getServerState(); |
| } |
| |
| protected IStatus publishImpl(int kind, List<IModule[]> modules4, IAdaptable info, IProgressMonitor monitor) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "-->-- Publishing to server: " + Server.this.toString() + " -->--"); |
| } |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Server.publishImpl(): kind=<" + getPublishKindString(kind) + "> modules=" |
| + modules4); |
| } |
| |
| stopAutoPublish(); |
| |
| try { |
| long time = System.currentTimeMillis(); |
| firePublishStarted(); |
| |
| getServerPublishInfo().startCaching(); |
| IStatus status = Status.OK_STATUS; |
| try { |
| getBehaviourDelegate(monitor).publish(kind, modules4, monitor, info); |
| } catch (CoreException ce) { |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, |
| "Error during publishing", ce); |
| } |
| status = ce.getStatus(); |
| } |
| |
| final List<IModule[]> modules2 = new ArrayList<IModule[]>(); |
| visit(new IModuleVisitor() { |
| public boolean visit(IModule[] module) { |
| if (getModulePublishState(module) == IServer.PUBLISH_STATE_NONE) |
| getServerPublishInfo().fill(module); |
| |
| modules2.add(module); |
| return true; |
| } |
| }, monitor); |
| |
| getServerPublishInfo().removeDeletedModulePublishInfo(Server.this, modules2); |
| getServerPublishInfo().clearCache(); |
| getServerPublishInfo().save(); |
| |
| firePublishFinished(Status.OK_STATUS); |
| if (Trace.PERFORMANCE) { |
| Trace.trace(Trace.STRING_PERFORMANCE, "Server.publishImpl(): <" + (System.currentTimeMillis() - time) |
| + "> " + getServerType().getId()); |
| } |
| return status; |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace( |
| Trace.STRING_SEVERE, |
| "Error calling delegate publish() " |
| + Server.this.toString(), e); |
| } |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishing, e); |
| } |
| } |
| |
| protected IStatus restartImpl(String launchMode, IProgressMonitor monitor) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Restarting server: " + getName()); |
| } |
| |
| try { |
| try { |
| // synchronous restart |
| restartImpl2(launchMode, monitor); |
| |
| return Status.OK_STATUS; |
| } catch (CoreException ce) { |
| if (ce.getStatus().getCode() != -1) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, "Error calling delegate restart() " + Server.this.toString()); |
| } |
| return ce.getStatus(); |
| } |
| } |
| // if restart is not implemented by the server adopter |
| // lets provide a default implementation |
| stop(false); |
| start(launchMode, monitor); |
| |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, "Error restarting server", e); |
| } |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorStartFailed, getName()), e); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Synchroneous restart. Throws a core exception in case the the adopter doesn't implement restart |
| * @param launchMode |
| * @param monitor |
| * @return IStatus |
| * @throws CoreException |
| */ |
| protected IStatus restartImpl2(String launchMode, IProgressMonitor monitor) throws CoreException{ |
| final boolean[] notified = new boolean[1]; |
| |
| // add listener to the server |
| IServerListener listener = new IServerListener() { |
| public void serverChanged(ServerEvent event) { |
| int eventKind = event.getKind(); |
| IServer server = event.getServer(); |
| if (eventKind == (ServerEvent.SERVER_CHANGE | ServerEvent.STATE_CHANGE)) { |
| int state = server.getServerState(); |
| if (state == IServer.STATE_STARTED) { |
| // notify waiter |
| synchronized (notified) { |
| try { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousRestart notify"); |
| } |
| notified[0] = true; |
| notified.notifyAll(); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying server restart", e); |
| } |
| } |
| } |
| } |
| } |
| } |
| }; |
| addServerListener(listener); |
| |
| final int restartTimeout = (getStartTimeout() * 1000) + (getStopTimeout() * 1000); |
| class Timer { |
| boolean timeout; |
| boolean alreadyDone; |
| } |
| final Timer timer = new Timer(); |
| |
| final IProgressMonitor monitor2 = monitor; |
| Thread thread = new Thread("Server Restart Timeout") { |
| public void run() { |
| try { |
| int totalTimeout = restartTimeout; |
| if (totalTimeout < 0) |
| totalTimeout = 1; |
| boolean userCancelled = false; |
| int retryPeriod = 2500; |
| while (!notified[0] && totalTimeout > 0 && !userCancelled && !timer.alreadyDone) { |
| Thread.sleep(retryPeriod); |
| if (restartTimeout > 0) |
| totalTimeout -= retryPeriod; |
| if (!notified[0] && !timer.alreadyDone && monitor2.isCanceled()) { |
| // user canceled - set the server state to stopped |
| userCancelled = true; |
| if (launch != null && !launch.isTerminated()) |
| launch.terminate(); |
| // notify waiter |
| synchronized (notified) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousRestart user cancelled"); |
| } |
| notified[0] = true; |
| notified.notifyAll(); |
| } |
| } |
| } |
| if (!userCancelled && !timer.alreadyDone && !notified[0]) { |
| // notify waiter |
| synchronized (notified) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousRestart notify timeout"); |
| } |
| if (!timer.alreadyDone && totalTimeout <= 0) |
| timer.timeout = true; |
| notified[0] = true; |
| notified.notifyAll(); |
| } |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying server restart timeout", e); |
| } |
| } |
| } |
| }; |
| thread.setDaemon(true); |
| thread.start(); |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousRestart 2"); |
| } |
| |
| // call the delegate restart |
| try { |
| getBehaviourDelegate(null).restart(launchMode); |
| } catch (CoreException e) { |
| removeServerListener(listener); |
| timer.alreadyDone = true; |
| throw new CoreException(e.getStatus()); |
| } |
| if (monitor.isCanceled()) { |
| removeServerListener(listener); |
| timer.alreadyDone = true; |
| return Status.CANCEL_STATUS; |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousRestart 3"); |
| } |
| |
| // wait for it! wait for it! ... |
| synchronized (notified) { |
| try { |
| while (!notified[0] && !monitor.isCanceled() && !timer.timeout |
| && !(getServerState() == IServer.STATE_STARTED)) { |
| notified.wait(); |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error waiting for server restart", e); |
| } |
| } |
| timer.alreadyDone = true; |
| } |
| removeServerListener(listener); |
| |
| if (timer.timeout) { |
| stop(false); |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorRestartTimeout, new String[] { getName(), (restartTimeout / 1000) + "" }), null); |
| } |
| |
| if (!monitor.isCanceled() && getServerState() == IServer.STATE_STOPPED) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorRestartFailed, getName()), null); |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousRestart 4"); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| protected IStatus startImpl(String launchMode, IProgressMonitor monitor) { |
| final boolean[] notified = new boolean[1]; |
| |
| monitor = ProgressUtil.getMonitorFor(monitor); |
| |
| // add listener to the server |
| IServerListener listener = new IServerListener() { |
| public void serverChanged(ServerEvent event) { |
| int eventKind = event.getKind(); |
| IServer server = event.getServer(); |
| if (eventKind == (ServerEvent.SERVER_CHANGE | ServerEvent.STATE_CHANGE)) { |
| int state = server.getServerState(); |
| if (state == IServer.STATE_STARTED || state == IServer.STATE_STOPPED) { |
| // notify waiter |
| synchronized (notified) { |
| try { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousStart notify"); |
| } |
| notified[0] = true; |
| notified.notifyAll(); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying server start", e); |
| } |
| } |
| } |
| } |
| } |
| } |
| }; |
| addServerListener(listener); |
| |
| final int serverTimeout = getStartTimeout() * 1000; |
| class Timer { |
| boolean timeout; |
| boolean alreadyDone; |
| } |
| final Timer timer = new Timer(); |
| |
| final IProgressMonitor monitor2 = monitor; |
| Thread thread = new Thread("Server Start Timeout") { |
| public void run() { |
| try { |
| int totalTimeout = serverTimeout; |
| if (totalTimeout < 0) |
| totalTimeout = 1; |
| boolean userCancelled = false; |
| int retryPeriod = 1000; |
| while (!notified[0] && totalTimeout > 0 && !userCancelled && !timer.alreadyDone) { |
| Thread.sleep(retryPeriod); |
| if (serverTimeout > 0) |
| totalTimeout -= retryPeriod; |
| if (!notified[0] && !timer.alreadyDone && monitor2.isCanceled()) { |
| // user canceled - set the server state to stopped |
| userCancelled = true; |
| if (launch != null && !launch.isTerminated()) |
| launch.terminate(); |
| // notify waiter |
| synchronized (notified) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousStart user cancelled"); |
| } |
| notified[0] = true; |
| notified.notifyAll(); |
| } |
| } |
| } |
| if (!userCancelled && !timer.alreadyDone && !notified[0]) { |
| // notify waiter |
| synchronized (notified) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousStart notify timeout"); |
| } |
| if (!timer.alreadyDone && totalTimeout <= 0) |
| timer.timeout = true; |
| notified[0] = true; |
| notified.notifyAll(); |
| } |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying server start timeout", e); |
| } |
| } |
| } |
| }; |
| thread.setDaemon(true); |
| thread.start(); |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousStart 2"); |
| } |
| |
| // start the server |
| try { |
| startImpl2(launchMode, monitor); |
| } catch (CoreException e) { |
| removeServerListener(listener); |
| timer.alreadyDone = true; |
| return e.getStatus(); |
| } |
| if (monitor.isCanceled()) { |
| removeServerListener(listener); |
| timer.alreadyDone = true; |
| return Status.CANCEL_STATUS; |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousStart 3"); |
| } |
| |
| // wait for it! wait for it! ... |
| synchronized (notified) { |
| try { |
| while (!notified[0] && !monitor.isCanceled() && !timer.timeout |
| && !(getServerState() == IServer.STATE_STARTED || getServerState() == IServer.STATE_STOPPED)) { |
| notified.wait(); |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error waiting for server start", e); |
| } |
| } |
| timer.alreadyDone = true; |
| } |
| removeServerListener(listener); |
| |
| if (timer.timeout) { |
| stop(false); |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorStartTimeout, new String[] { getName(), (serverTimeout / 1000) + "" }), null); |
| } |
| |
| if (!monitor.isCanceled() && getServerState() == IServer.STATE_STOPPED) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorStartFailed, getName()), null); |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "synchronousStart 4"); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| protected void startImpl2(String mode2, IProgressMonitor monitor) throws CoreException { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Starting server: " + Server.this.toString() + ", launchMode: " + mode2); |
| } |
| SaveEditorPrompter editorHelper = (ServerPlugin.isRunningGUIMode()) ? ServerPlugin.getSaveEditorHelper() : null; |
| // make sure that the delegate is loaded and the server state is correct |
| loadAdapter(ServerBehaviourDelegate.class, monitor); |
| |
| try { |
| ILaunchConfiguration launchConfig = getLaunchConfiguration(true, monitor); |
| |
| if (editorHelper != null){ |
| editorHelper.setDebugNeverSave(); |
| } |
| |
| if (launchConfig != null){ |
| launch = launchConfig.launch(mode2, monitor); // , true); - causes workspace lock |
| } |
| |
| if (editorHelper != null){ |
| editorHelper.setDebugOriginalValue(); |
| } |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Launch: " + launch); |
| } |
| } catch (CoreException e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, "Error starting server " |
| + Server.this.toString(), e); |
| } |
| throw e; |
| } |
| } |
| |
| protected IStatus stopImpl(boolean force, IProgressMonitor monitor) { |
| final Object mutex = new Object(); |
| |
| // add listener to the server |
| IServerListener listener = new IServerListener() { |
| public void serverChanged(ServerEvent event) { |
| int eventKind = event.getKind(); |
| IServer server = event.getServer(); |
| if (eventKind == (ServerEvent.SERVER_CHANGE | ServerEvent.STATE_CHANGE)) { |
| int state = server.getServerState(); |
| if (Server.this == server && (state == IServer.STATE_STOPPED || state == IServer.STATE_STARTED)) { |
| // notify waiter |
| synchronized (mutex) { |
| try { |
| mutex.notifyAll(); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying server stop", e); |
| } |
| } |
| } |
| } |
| } |
| } |
| }; |
| addServerListener(listener); |
| |
| class Timer { |
| boolean timeout; |
| boolean alreadyDone; |
| } |
| final Timer timer = new Timer(); |
| |
| final int serverTimeout = getStopTimeout() * 1000; |
| if (serverTimeout > 0) { |
| Thread thread = new Thread("Server Stop Timeout") { |
| public void run() { |
| try { |
| Thread.sleep(serverTimeout); |
| if (!timer.alreadyDone) { |
| timer.timeout = true; |
| // notify waiter |
| synchronized (mutex) { |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "stop notify timeout"); |
| } |
| mutex.notifyAll(); |
| } |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error notifying server stop timeout", e); |
| } |
| } |
| } |
| }; |
| thread.setDaemon(true); |
| thread.start(); |
| } |
| |
| // stop the server |
| stopImpl2(force); |
| |
| // wait for it! wait for it! |
| synchronized (mutex) { |
| try { |
| while (!timer.timeout && getServerState() != IServer.STATE_STOPPED && |
| getServerState() != IServer.STATE_STARTED) |
| mutex.wait(); |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, |
| "Error waiting for server stop", e); |
| } |
| } |
| } |
| removeServerListener(listener); |
| |
| //can't throw exceptions |
| /*if (timer.timeout) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorStopTimeout, getName()), null); |
| else |
| timer.alreadyDone = true; |
| */ |
| if (!monitor.isCanceled() && getServerState() == IServer.STATE_STARTED) |
| return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorStopFailed, getName()), null); |
| |
| return Status.OK_STATUS; |
| } |
| |
| protected void stopImpl2(boolean force) { |
| if (getServerState() == STATE_STOPPED) |
| return; |
| |
| if (Trace.FINEST) { |
| Trace.trace(Trace.STRING_FINEST, "Stopping server: " + Server.this.toString()); |
| } |
| |
| try { |
| getBehaviourDelegate(null).stop(force); |
| } catch (RuntimeException e) { |
| if (Trace.SEVERE) { |
| Trace.trace( |
| Trace.STRING_SEVERE, |
| "Error calling delegate stop() " |
| + Server.this.toString(), e); |
| } |
| throw e; |
| } catch (Throwable t) { |
| if (Trace.SEVERE) { |
| Trace.trace( |
| Trace.STRING_SEVERE, |
| "Error calling delegate stop() " |
| + Server.this.toString(), t); |
| } |
| throw new RuntimeException(t); |
| } |
| } |
| |
| public boolean contains(ISchedulingRule rule) { |
| return (rule instanceof IServer || rule instanceof ServerSchedulingRule); |
| } |
| |
| public boolean isConflicting(ISchedulingRule rule) { |
| if (!(rule instanceof IServer) && !(rule instanceof ServerSchedulingRule)) |
| return false; |
| |
| if (rule instanceof IServer) { |
| IServer s = (IServer) rule; |
| return this.equals(s); |
| } |
| ServerSchedulingRule ssrule = (ServerSchedulingRule) rule; |
| return ssrule.server.equals(this); |
| } |
| |
| public String toString() { |
| return getName(); |
| } |
| |
| private String getPublishKindString(int kind){ |
| if (kind == IServer.PUBLISH_AUTO){ |
| return PUBLISH_AUTO_STRING; |
| } |
| else if (kind == IServer.PUBLISH_CLEAN){ |
| return PUBLISH_CLEAN_STRING; |
| } |
| else if (kind == IServer.PUBLISH_FULL){ |
| return PUBLISH_FULL_STRING; |
| } |
| else if (kind == IServer.PUBLISH_INCREMENTAL){ |
| return PUBLISH_INCREMENTAL_STRING; |
| } |
| return PUBLISH_UNKOWN; |
| } |
| } |