Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravera2010-07-14 21:03:13 +0000
committeravera2010-07-14 21:03:13 +0000
commit95166fb093fd77b758aa3fed4c3e5668effde1ac (patch)
tree04f8cc993291282c082953bb39d772e74e5ad18a /plugins/org.eclipse.wst.server.core/servercore/org/eclipse
parentb8137ac4b6f6ac90c41e18221006b373b7149a18 (diff)
downloadwebtools.servertools-95166fb093fd77b758aa3fed4c3e5668effde1ac.tar.gz
webtools.servertools-95166fb093fd77b758aa3fed4c3e5668effde1ac.tar.xz
webtools.servertools-95166fb093fd77b758aa3fed4c3e5668effde1ac.zip
[319288] Publishers may either cause lock conflicts or duplicate publishes
Diffstat (limited to 'plugins/org.eclipse.wst.server.core/servercore/org/eclipse')
-rw-r--r--plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Publisher.java122
-rw-r--r--plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPublishInfo.java17
-rw-r--r--plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/PublisherDelegate.java33
-rw-r--r--plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/ServerBehaviourDelegate.java82
4 files changed, 208 insertions, 46 deletions
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Publisher.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Publisher.java
index 9ce878179..f125d754c 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Publisher.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Publisher.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2010 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
@@ -10,12 +10,14 @@
*******************************************************************************/
package org.eclipse.wst.server.core.internal;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IServerWorkingCopy;
import org.eclipse.wst.server.core.TaskModel;
import org.eclipse.wst.server.core.model.PublisherDelegate;
/**
@@ -24,6 +26,7 @@ import org.eclipse.wst.server.core.model.PublisherDelegate;
public class Publisher {
private IConfigurationElement element;
private PublisherDelegate delegate;
+ private boolean modifyModules = false;
/**
* Publisher constructor comment.
@@ -78,14 +81,101 @@ public class Publisher {
return delegate;
}
+ /**
+ * Should the original {@link ISchedulingRule} be changed with the new {@link ISchedulingRule}?
+ *
+ * @param originalRule
+ * The original {@link ISchedulingRule}
+ * @param newRule
+ * The new {@link ISchedulingRule}
+ * @return <code>true</code> if the new scheduling rule should be applied; Otherwise <code>false</code>.
+ */
+ private boolean changeSchedulingRule(ISchedulingRule originalRule, ISchedulingRule newRule) {
+
+ boolean changeRule = false;
+ if ((originalRule == null) && (newRule == null)) {
+ // no need to change rules if they're both null
+ changeRule = false;
+ }
+ else if((originalRule == null) && (newRule != null)) {
+ // there is currently no rule and a new not-null rule wants to be added
+ changeRule = true;
+ }
+ else if((originalRule != null) && (newRule == null)) {
+ // there is currently a rule and a new null rule wants to be applied
+ changeRule = true;
+ }
+ else if((originalRule != null) && (newRule != null)) {
+ // there is currently a rule and a new not-null rule wants to be applied.
+ changeRule = !originalRule.equals(newRule);
+ }
+ return changeRule;
+ }
+
+ /**
+ * rebuild the cache for the modules involved with this task.
+ */
+ private void rebuildModuleCache() {
+
+ // reset the publishing cache for the modules that are part of this task.
+ Server server = (Server) getDelegate().getTaskModel().getObject(TaskModel.TASK_SERVER);
+ if (server != null) {
+ // make sure the right server is used.
+ if(server.isWorkingCopy()) {
+ IServerWorkingCopy workingCopy = (IServerWorkingCopy)server;
+ server = (Server) workingCopy.getOriginal();
+ }
+ final List moduleList = (List)getDelegate().getTaskModel().getObject(TaskModel.TASK_MODULES);
+ if (moduleList != null) {
+ final Iterator moduleIterator = moduleList.iterator();
+ while (moduleIterator.hasNext()) {
+ IModule[] module = (IModule[]) moduleIterator.next();
+ if (module != null) {
+ Trace.trace(Trace.FINEST, "rebuilding cache for module: " + module[module.length - 1]);
+ server.getServerPublishInfo().rebuildCache(module);
+ }
+ }
+ }
+ }
+ }
+
public IStatus execute(int kind, IProgressMonitor monitor, IAdaptable info) throws CoreException {
+
+ Trace.trace(Trace.FINEST, "Task.init " + this);
+ ISchedulingRule delegatePublisherRule = null;
+ final ISchedulingRule originalPublisherRule = Job.getJobManager().currentRule();
+ IStatus resultStatus = null;
+ boolean changeSchedulingRules = false;
try {
- Trace.trace(Trace.FINEST, "Task.init " + this);
- return getDelegate().execute(kind, monitor, info);
- } catch (Exception e) {
+ delegatePublisherRule = getDelegate().getRule();
+ changeSchedulingRules = this.changeSchedulingRule(originalPublisherRule, delegatePublisherRule);
+ Trace.trace(Trace.FINEST, "Change the scheduling rule to execute delegate: " + changeSchedulingRules);
+ if (changeSchedulingRules) {
+ Trace.trace(Trace.FINEST, "Ending the current scheduling rule " + originalPublisherRule);
+ Job.getJobManager().endRule(originalPublisherRule);
+ Trace.trace(Trace.FINEST, "Beginning the new scheduling rule: " + delegatePublisherRule);
+ Job.getJobManager().beginRule(delegatePublisherRule, monitor);
+ }
+ resultStatus = getDelegate().execute(kind, monitor, info);
+ this.modifyModules = getDelegate().isModifyModules();
+ Trace.trace(Trace.FINEST, "The publisher delegate stated that it modified modules: " + this.modifyModules);
+ if(this.modifyModules) {
+ this.rebuildModuleCache();
+ }
+ }
+ catch (Exception e) {
Trace.trace(Trace.SEVERE, "Error calling delegate " + toString(), e);
- return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, "Error in delegate", e); // TODO
+ resultStatus = new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, "Error in delegate", e); // TODO
}
+ finally {
+ if (changeSchedulingRules) {
+ Trace.trace(Trace.FINEST, "Reseting the scheduling rules... ending: " + delegatePublisherRule);
+ Job.getJobManager().endRule(delegatePublisherRule);
+ Trace.trace(Trace.FINEST, "Reseting the scheduling rules... beginning: " + originalPublisherRule);
+ Job.getJobManager().beginRule(originalPublisherRule, monitor);
+ }
+ }
+ return resultStatus;
}
public void setTaskModel(TaskModel taskModel) {
@@ -97,6 +187,16 @@ public class Publisher {
}
/**
+ * Accessor to find out if this publisher modified any modules that are published on the server.
+ *
+ * @return <code>true</code> if the publisher modified the contents of any modules that are published on the server.
+ */
+ public boolean isModifyModules() {
+
+ return this.modifyModules;
+ }
+
+ /**
* Return a string representation of this object.
*
* @return a string
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPublishInfo.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPublishInfo.java
index 921000312..eadd3c8fd 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPublishInfo.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerPublishInfo.java
@@ -540,4 +540,21 @@ public class ServerPublishInfo {
}
}
}
+
+ /**
+ * Recreates the cache for the specified {@link IModule}.
+ *
+ * @param module The {@link IModule}
+ */
+ public void rebuildCache(IModule[] module) {
+
+ synchronized (modulePublishInfo) {
+ final String publishInfoKey = this.getKey(module);
+ ModulePublishInfo mpi = modulePublishInfo.get(publishInfoKey);
+ if(mpi != null) {
+ mpi.startCaching(); // clear out the resource list
+ mpi.fill(module); // rebuild the resource list
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/PublisherDelegate.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/PublisherDelegate.java
index e4b70935e..564b322c0 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/PublisherDelegate.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/PublisherDelegate.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2010 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
@@ -10,10 +10,9 @@
*******************************************************************************/
package org.eclipse.wst.server.core.model;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.wst.server.core.TaskModel;
/**
* An operation that will be executed during publishing.
@@ -91,4 +90,28 @@ public abstract class PublisherDelegate {
* @throws CoreException if there was an error while executing the task
*/
public abstract IStatus execute(int kind, IProgressMonitor monitor, IAdaptable info) throws CoreException;
+
+ /**
+ * Returns the scheduling rule that is required for executing the publisher delegate. The default is the current
+ * rule defined on the publishing job.
+ *
+ * @return A {@link ISchedulingRule} for the job that defines how this publisher can execute in the publishing job.
+ * A <code>null</code> value may be returned if the publishing job does not have any rule defined.
+ * @since 3.2
+ */
+ public ISchedulingRule getRule() {
+
+ return Job.getJobManager().currentRule();
+ }
+
+ /**
+ * Accessor to find out if this publisher delegate modified any modules that are published on the server.
+ *
+ * @return <code>true</code> if the publisher modified the contents of any modules that are published on the server.
+ * @since 3.2
+ */
+ public boolean isModifyModules() {
+
+ return false;
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/ServerBehaviourDelegate.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/ServerBehaviourDelegate.java
index ca4692987..dad47aa3a 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/ServerBehaviourDelegate.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/model/ServerBehaviourDelegate.java
@@ -863,6 +863,33 @@ public abstract class ServerBehaviourDelegate {
multi.addAll(tempMulti);
}*/
+ private List<Integer> computeDelta(final List<IModule[]> moduleList) {
+
+ final List<Integer> deltaKindList = new ArrayList<Integer>();
+ final Iterator<IModule[]> iterator = moduleList.iterator();
+ while (iterator.hasNext()) {
+ IModule[] module = iterator.next();
+ if (hasBeenPublished(module)) {
+ IModule m = module[module.length - 1];
+ if ((m.getProject() != null && !m.getProject().isAccessible())
+ || getPublishedResourceDelta(module).length == 0) {
+ deltaKindList.add(new Integer(ServerBehaviourDelegate.NO_CHANGE));
+ }
+ else {
+ deltaKindList.add(new Integer(ServerBehaviourDelegate.CHANGED));
+ }
+ }
+ else {
+ deltaKindList.add(new Integer(ServerBehaviourDelegate.ADDED));
+ }
+ }
+ this.addRemovedModules(moduleList, null);
+ while (deltaKindList.size() < moduleList.size()) {
+ deltaKindList.add(new Integer(ServerBehaviourDelegate.REMOVED));
+ }
+ return deltaKindList;
+ }
+
/**
* Publish to the server.
*
@@ -878,25 +905,7 @@ public abstract class ServerBehaviourDelegate {
return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishNoRuntime, null);
final List<IModule[]> moduleList = getAllModules();
- final List<Integer> deltaKindList = new ArrayList<Integer>();
-
- Iterator iterator = moduleList.iterator();
- while (iterator.hasNext()) {
- IModule[] module = (IModule[]) iterator.next();
- if (hasBeenPublished(module)) {
- IModule m = module[module.length - 1];
- if ((m.getProject() != null && !m.getProject().isAccessible())
- || getPublishedResourceDelta(module).length == 0)
- deltaKindList.add(new Integer(ServerBehaviourDelegate.NO_CHANGE));
- else
- deltaKindList.add(new Integer(ServerBehaviourDelegate.CHANGED));
- } else
- deltaKindList.add(new Integer(ServerBehaviourDelegate.ADDED));
- }
-
- addRemovedModules(moduleList, null);
- while (deltaKindList.size() < moduleList.size())
- deltaKindList.add(new Integer(ServerBehaviourDelegate.REMOVED));
+ List<Integer> deltaKindList = this.computeDelta(moduleList);
PublishOperation[] tasks = getTasks(kind, moduleList, deltaKindList);
int size = 2000 + 3500 * moduleList.size() + 500 * tasks.length;
@@ -1144,18 +1153,22 @@ public abstract class ServerBehaviourDelegate {
}
/**
- * Execute publishers.
+ * Execute publishers. If a publisher modified the contents of the module (which is determined by the
+ * {@link PublisherDelegate}) then the delta list is rebuild.
*
- * @param kind the publish kind
- * @param modules the list of modules
- * @param deltaKinds the list of delta kind that maps to the list of modules
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @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
- * org.eclipse.swt.widgets.Shell.class
+ * @param kind
+ * the publish kind
+ * @param modules
+ * the list of modules. The contents of this {@link List} may change if the publisher modifies code.
+ * @param deltaKinds
+ * the list of delta kind that maps to the list of modules. The contents of this {@link List} may change
+ * if the publisher modifies code.
+ * @param monitor
+ * a progress monitor, or <code>null</code> if progress reporting and cancellation are not desired
+ * @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 org.eclipse.swt.widgets.Shell.class
* @throws CoreException
* @since 1.1
*/
@@ -1176,12 +1189,17 @@ public abstract class ServerBehaviourDelegate {
taskModel.putObject(TaskModel.TASK_DELTA_KINDS, deltaKinds);
}
+ boolean publisherModifiedCode = false;
for (int i = 0; i < size; i++) {
Publisher pub = publishers[i];
monitor.subTask(NLS.bind(Messages.taskPerforming, pub.getName()));
try {
pub.setTaskModel(taskModel);
IStatus pubStatus = pub.execute(kind, ProgressUtil.getSubMonitorFor(monitor, 500), info);
+ if(!publisherModifiedCode) {
+ // If a publisher has modified modules then there is no reason to keep checking other publishers.
+ publisherModifiedCode = pub.isModifyModules();
+ }
multi.add(pubStatus);
} catch (CoreException ce) {
Trace.trace(Trace.SEVERE, "Publisher failed", ce);
@@ -1192,6 +1210,10 @@ public abstract class ServerBehaviourDelegate {
if (monitor.isCanceled())
return multi;
}
+ if (publisherModifiedCode) {
+ // re-create the delta list as at least one publisher has changed the contents of the published modules.
+ deltaKinds = this.computeDelta(modules);
+ }
return multi;
}

Back to the top