Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2011-03-21 19:45:27 +0000
committerThomas Watson2011-03-21 19:45:27 +0000
commit114de503c7d557b50bee8409b31af521a194f8e3 (patch)
treee1bfe37f1a518c296d56fb5d874300fe55df85b3 /bundles/org.eclipse.equinox.coordinator
parent1b61fe742323390070f4d2bfa12ee294e2e37d1e (diff)
downloadrt.equinox.bundles-114de503c7d557b50bee8409b31af521a194f8e3.tar.gz
rt.equinox.bundles-114de503c7d557b50bee8409b31af521a194f8e3.tar.xz
rt.equinox.bundles-114de503c7d557b50bee8409b31af521a194f8e3.zip
Work around bug 333513. Fix to remove CR chars.v20110321
Diffstat (limited to 'bundles/org.eclipse.equinox.coordinator')
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Activator.java94
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java774
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationTimerTask.java74
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorComponent.java128
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java584
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java84
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogMessages.properties34
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTracker.java350
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTrackerMsg.java56
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java94
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties62
11 files changed, 1167 insertions, 1167 deletions
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Activator.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Activator.java
index fc890d6de..eceb8dc77 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Activator.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Activator.java
@@ -1,47 +1,47 @@
-/*******************************************************************************
- * Copyright (c) 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
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.coordinator;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.coordinator.Coordinator;
-
-public class Activator implements BundleActivator {
- // Static so the factory can be used by both DS and standard OSGi.
- static volatile CoordinatorServiceFactory factory;
-
- private ServiceRegistration<Coordinator> registration;
-
- public void start(BundleContext bundleContext) throws Exception {
- // Instantiate the factory to be used by both DS and standard OSGi. In the case of DS, the
- // start method is guaranteed to be called before any components are created.
- factory = new CoordinatorServiceFactory(bundleContext);
- if (Boolean.valueOf(bundleContext.getProperty("equinox.use.ds")).booleanValue()) //$NON-NLS-1$
- return; // If this property is set we assume DS is being used.
- Dictionary<String, Object> properties = new Hashtable<String, Object>();
- // TODO Add desired properties (bundle vendor, etc.).
- @SuppressWarnings({"unchecked"})
- // Use local variable to avoid suppressing unchecked warnings at method level.
- ServiceRegistration<Coordinator> reg = (ServiceRegistration<Coordinator>) bundleContext.registerService(Coordinator.class.getName(), factory, properties);
- this.registration = reg;
- }
-
- public void stop(BundleContext bundleContext) throws Exception {
- // Will be null when using DS.
- if (registration != null)
- registration.unregister();
- factory.shutdown();
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.coordinator.Coordinator;
+
+public class Activator implements BundleActivator {
+ // Static so the factory can be used by both DS and standard OSGi.
+ static volatile CoordinatorServiceFactory factory;
+
+ private ServiceRegistration<Coordinator> registration;
+
+ public void start(BundleContext bundleContext) throws Exception {
+ // Instantiate the factory to be used by both DS and standard OSGi. In the case of DS, the
+ // start method is guaranteed to be called before any components are created.
+ factory = new CoordinatorServiceFactory(bundleContext);
+ if (Boolean.valueOf(bundleContext.getProperty("equinox.use.ds")).booleanValue()) //$NON-NLS-1$
+ return; // If this property is set we assume DS is being used.
+ Dictionary<String, Object> properties = new Hashtable<String, Object>();
+ // TODO Add desired properties (bundle vendor, etc.).
+ @SuppressWarnings({"unchecked"})
+ // Use local variable to avoid suppressing unchecked warnings at method level.
+ ServiceRegistration<Coordinator> reg = (ServiceRegistration<Coordinator>) bundleContext.registerService(Coordinator.class.getName(), factory, properties);
+ this.registration = reg;
+ }
+
+ public void stop(BundleContext bundleContext) throws Exception {
+ // Will be null when using DS.
+ if (registration != null)
+ registration.unregister();
+ factory.shutdown();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java
index 4abdca780..bfc283911 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java
@@ -1,387 +1,387 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 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.equinox.coordinator;
-
-import java.lang.ref.Reference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimerTask;
-
-import org.osgi.framework.Bundle;
-import org.osgi.service.coordinator.Coordination;
-import org.osgi.service.coordinator.CoordinationException;
-import org.osgi.service.coordinator.CoordinationPermission;
-import org.osgi.service.coordinator.Participant;
-import org.osgi.service.log.LogService;
-
-public class CoordinationImpl implements Coordination {
- private volatile Throwable failure;
- private volatile boolean terminated;
-
- private Date deadline;
- private Reference<CoordinationImpl> enclosingCoordination;
- private Thread thread;
- private TimerTask timerTask;
-
- private final CoordinatorImpl coordinator;
- private final long id;
- private final String name;
- private final List<Participant> participants;
- private final Map<Class<?>, Object> variables;
-
- public CoordinationImpl(long id, String name, long timeout, CoordinatorImpl coordinator) {
- validateName(name);
- validateTimeout(timeout);
- this.id = id;
- this.name = name;
- this.deadline = new Date(System.currentTimeMillis() + timeout);
- this.coordinator = coordinator;
- participants = Collections.synchronizedList(new ArrayList<Participant>());
- variables = new HashMap<Class<?>, Object>();
- }
-
- public void addParticipant(Participant participant) throws CoordinationException {
- // This method requires the PARTICIPATE permission.
- coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
- if (participant == null)
- throw new NullPointerException(Messages.CoordinationImpl_15);
- /* The caller has permission. Check to see if the participant is already
- * participating in another coordination. Do this in a loop in case the
- * participant must wait for the other coordination to finish. The loop
- * will exit under the following circumstances.
- *
- * (1) This coordination is terminated.
- * (2) The participant is already participating in another coordination
- * using the same thread as this one.
- * (3) This thread is interrupted.
- * (4) The participant is not participating in another coordination.
- */
- while (true) {
- CoordinationImpl coordination;
- synchronized (this) {
- // Check to see if this coordination has already terminated. If so,
- // throw the appropriate exception.
- checkTerminated();
- coordination = coordinator.addParticipant(participant, this);
- if (coordination == null) {
- // The same participant is not currently participating in
- // any coordination. Add it to this coordination and break
- // out of the loop.
- participants.add(participant);
- break;
- } else if (coordination == this) {
- // The same participant is being added twice to this
- // coordination. Nothing to do.
- break;
- } else {
- // This means the participant is already participating in another
- // coordination. Check to see if it's on the same thread.
- Thread t = coordination.getThread();
- // If thread is null, the coordination is not associated with
- // any thread, and there's nothing to compare. If the coordination
- // is using this thread, then we can't block due to risk of deadlock.
- if (t == Thread.currentThread()) {
- throw new CoordinationException(Messages.CoordinationImpl_1, CoordinationImpl.this, CoordinationException.DEADLOCK_DETECTED);
- }
- }
- }
- // The participant is already participating in another coordination
- // that's not using this thread. Block until that coordination has
- // finished. A decision was made here to use a timeout and incur the
- // expense of waking up and rejoining in order to make a reasonably
- // timely exit if this coordination terminates.
- try {
- coordination.join(1000);
- } catch (InterruptedException e) {
- coordinator.getLogService().log(LogService.LOG_DEBUG, Messages.CoordinationImpl_2, e);
- // This thread was interrupted while waiting for the coordination
- // to terminate.
- throw new CoordinationException(Messages.CoordinationImpl_3, CoordinationImpl.this, CoordinationException.LOCK_INTERRUPTED, e);
- }
- }
- }
-
- public void end() throws CoordinationException {
- coordinator.checkPermission(CoordinationPermission.INITIATE, name);
- // Terminating the coordination must be atomic.
- synchronized (this) {
- // If this coordination is associated with a thread, an additional
- // check is required.
- if (thread != null) {
- // Coordinations may only be ended by the same thread that
- // pushed them onto the stack, if any.
- if (thread != Thread.currentThread()) {
- throw new CoordinationException(Messages.CoordinationImpl_14, this, CoordinationException.WRONG_THREAD);
- }
- // Unwind the stack in case there are other coordinations higher
- // up than this one.
- while (coordinator.peek() != this) {
- try {
- coordinator.peek().end();
- } catch (CoordinationException e) {
- coordinator.peek().fail(e);
- }
- }
- // A coordination is removed from the thread local stack only when being ended.
- // This must occur even if the coordination is already terminated due to a
- // failure.
- coordinator.pop();
- }
- terminate();
- }
- // Notify participants this coordination has ended. Track whether or
- // not a partial ending has occurred.
- Exception exception = null;
- // No additional synchronization is needed here because the participant
- // list will not be modified post termination.
- for (Participant participant : participants) {
- try {
- participant.ended(this);
- } catch (Exception e) {
- coordinator.getLogService().log(LogService.LOG_WARNING, Messages.CoordinationImpl_4, e);
- // Only the first exception will be propagated.
- if (exception == null)
- exception = e;
- }
- }
- synchronized (this) {
- // Notify everything joined to this coordination that it has finished.
- notifyAll();
- }
- // If a partial ending has occurred, throw the required exception.
- if (exception != null) {
- throw new CoordinationException(Messages.CoordinationImpl_5, this, CoordinationException.PARTIALLY_ENDED, exception);
- }
- }
-
- public long extendTimeout(long timeInMillis) throws CoordinationException {
- coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
- validateTimeout(timeInMillis);
- // We don't want this coordination to terminate before the new timer is
- // in place.
- synchronized (this) {
- // Check to see if this coordination has already terminated. If so,
- // throw the appropriate exception.
- checkTerminated();
- // If there was no previous timeout set, return 0 indicating that no
- // extension has taken place.
- if (timerTask == null)
- return 0;
- // Passing anything less than zero as well as zero itself will return the
- // existing deadline. The deadline will not be null if timerTask is not null.
- if (timeInMillis == 0)
- return deadline.getTime();
- // Cancel the current timeout.
- boolean cancelled = timerTask.cancel();
- if (!cancelled) {
- // This means the previous task has run and is waiting to get a lock on
- // this coordination. We can't throw an exception yet because we can't
- // know which one to use (ALREADY_ENDED or FAILED). Once the lock is
- // released, the running task may fail this coordination due to a timeout,
- // or something else might be waiting to fail this coordination for other
- // reasons or to end it. We simply don't know who will win the race.
- try {
- // Wait until this coordination terminates.
- join(0);
- // Now determine how it terminated and throw the appropriate exception.
- checkTerminated();
- }
- catch (InterruptedException e) {
- throw new CoordinationException(Messages.CoordinationImpl_13, this, CoordinationException.UNKNOWN, e);
- }
- }
- // Create the new timeout.
- timerTask = new CoordinationTimerTask(this);
- // Extend the current deadline.
- deadline = new Date(deadline.getTime() + timeInMillis);
- // Schedule the new timeout.
- coordinator.schedule(timerTask, deadline);
- // Return the new deadline.
- return deadline.getTime();
- }
- }
-
- public boolean fail(Throwable reason) {
- coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
- // The reason must not be null.
- if (reason == null)
- throw new NullPointerException(Messages.CoordinationImpl_11);
- // Terminating the coordination must be atomic.
- synchronized (this) {
- // If this coordination is terminated, return false. Do not throw a
- // CoordinationException as in other methods.
- if (terminated)
- return false;
- // This coordination has not already terminated, so terminate now.
- terminate();
- // Store the reason for the failure.
- failure = reason;
- }
- // Notify participants this coordination has failed.
- // No additional synchronization is needed here because the participant
- // list will not be modified post termination.
- for (Participant participant : participants) {
- try {
- participant.failed(this);
- } catch (Exception e) {
- coordinator.getLogService().log(LogService.LOG_WARNING, Messages.CoordinationImpl_6, e);
- }
- }
- synchronized (this) {
- // Notify everything joined to this coordination that it has finished.
- notifyAll();
- }
- // Return true to indicate this call resulted in the coordination's failure.
- return true;
- }
-
- public Bundle getBundle() {
- coordinator.checkPermission(CoordinationPermission.ADMIN, name);
- return coordinator.getBundle();
- }
-
- public synchronized Coordination getEnclosingCoordination() {
- coordinator.checkPermission(CoordinationPermission.ADMIN, name);
- return enclosingCoordination == null ? null : enclosingCoordination.get();
- }
-
- public Throwable getFailure() {
- coordinator.checkPermission(CoordinationPermission.INITIATE, name);
- return failure;
- }
-
- public long getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-
- public List<Participant> getParticipants() {
- // This method requires the ADMIN permission.
- coordinator.checkPermission(CoordinationPermission.INITIATE, name);
- // Return a mutable snapshot.
- synchronized (participants) {
- return new ArrayList<Participant>(participants);
- }
- }
-
- public synchronized Thread getThread() {
- coordinator.checkPermission(CoordinationPermission.ADMIN, name);
- return thread;
- }
-
- public Map<Class<?>, Object> getVariables() {
- coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
- return variables;
- }
-
- public boolean isTerminated() {
- return terminated;
- }
-
- public void join(long timeInMillis) throws InterruptedException {
- coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
- long start = System.currentTimeMillis();
- // Wait until this coordination has terminated. Guard against spurious
- // wakeups using isTerminated().
- synchronized (this) {
- while (!terminated) {
- wait(timeInMillis);
- long elapsed = System.currentTimeMillis() - start;
- if (elapsed > timeInMillis)
- break;
- }
- }
- }
-
- public Coordination push() throws CoordinationException {
- coordinator.checkPermission(CoordinationPermission.INITIATE, name);
- synchronized (this) {
- checkTerminated();
- coordinator.push(this);
- }
- return this;
- }
-
- synchronized Date getDeadline() {
- return deadline;
- }
-
- LogService getLogService() {
- return coordinator.getLogService();
- }
-
- synchronized void setTimerTask(TimerTask timerTask) {
- this.timerTask = timerTask;
- }
-
- synchronized void setThreadAndEnclosingCoordination(Thread t, Reference<CoordinationImpl> c) {
- thread = t;
- enclosingCoordination = c;
- }
-
- private void checkTerminated() throws CoordinationException {
- // If this coordination is not terminated, simply return.
- if (!terminated)
- return;
- // The coordination has terminated. Figure out which type of exception
- // must be thrown.
- if (failure != null) {
- // The fail() method was called indicating the coordination failed.
- throw new CoordinationException(Messages.CoordinationImpl_7, this, CoordinationException.FAILED, failure);
- }
- // The coordination did not fail, so it either partially ended or
- // ended successfully.
- throw new CoordinationException(Messages.CoordinationImpl_8, CoordinationImpl.this, CoordinationException.ALREADY_ENDED);
- }
-
- private void terminate() throws CoordinationException {
- checkTerminated();
- terminated = true;
- // Cancel the timeout. Purge the task if it was, in fact, canceled.
- if (timerTask != null && timerTask.cancel()) {
- coordinator.purge();
- }
- coordinator.terminate(this, participants);
- }
-
- private static void validateName(String name) {
- boolean valid = true;
- if (name == null || name.length() == 0)
- valid = false;
- else {
- boolean period = false;
- for (char c : name.toCharArray()) {
- if (Character.isLetterOrDigit(c) || c == '_' || c == '-') {
- period = false;
- } else if (c == '.' && !period) {
- period = true;
- } else {
- valid = false;
- break;
- }
- }
- }
- if (!valid)
- throw new IllegalArgumentException(Messages.CoordinationImpl_10);
- }
-
- private static void validateTimeout(long timeout) {
- if (timeout < 0)
- throw new IllegalArgumentException(Messages.CoordinationImpl_12);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import java.lang.ref.Reference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimerTask;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.CoordinationException;
+import org.osgi.service.coordinator.CoordinationPermission;
+import org.osgi.service.coordinator.Participant;
+import org.osgi.service.log.LogService;
+
+public class CoordinationImpl implements Coordination {
+ private volatile Throwable failure;
+ private volatile boolean terminated;
+
+ private Date deadline;
+ private Reference<CoordinationImpl> enclosingCoordination;
+ private Thread thread;
+ private TimerTask timerTask;
+
+ private final CoordinatorImpl coordinator;
+ private final long id;
+ private final String name;
+ private final List<Participant> participants;
+ private final Map<Class<?>, Object> variables;
+
+ public CoordinationImpl(long id, String name, long timeout, CoordinatorImpl coordinator) {
+ validateName(name);
+ validateTimeout(timeout);
+ this.id = id;
+ this.name = name;
+ this.deadline = new Date(System.currentTimeMillis() + timeout);
+ this.coordinator = coordinator;
+ participants = Collections.synchronizedList(new ArrayList<Participant>());
+ variables = new HashMap<Class<?>, Object>();
+ }
+
+ public void addParticipant(Participant participant) throws CoordinationException {
+ // This method requires the PARTICIPATE permission.
+ coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
+ if (participant == null)
+ throw new NullPointerException(Messages.CoordinationImpl_15);
+ /* The caller has permission. Check to see if the participant is already
+ * participating in another coordination. Do this in a loop in case the
+ * participant must wait for the other coordination to finish. The loop
+ * will exit under the following circumstances.
+ *
+ * (1) This coordination is terminated.
+ * (2) The participant is already participating in another coordination
+ * using the same thread as this one.
+ * (3) This thread is interrupted.
+ * (4) The participant is not participating in another coordination.
+ */
+ while (true) {
+ CoordinationImpl coordination;
+ synchronized (this) {
+ // Check to see if this coordination has already terminated. If so,
+ // throw the appropriate exception.
+ checkTerminated();
+ coordination = coordinator.addParticipant(participant, this);
+ if (coordination == null) {
+ // The same participant is not currently participating in
+ // any coordination. Add it to this coordination and break
+ // out of the loop.
+ participants.add(participant);
+ break;
+ } else if (coordination == this) {
+ // The same participant is being added twice to this
+ // coordination. Nothing to do.
+ break;
+ } else {
+ // This means the participant is already participating in another
+ // coordination. Check to see if it's on the same thread.
+ Thread t = coordination.getThread();
+ // If thread is null, the coordination is not associated with
+ // any thread, and there's nothing to compare. If the coordination
+ // is using this thread, then we can't block due to risk of deadlock.
+ if (t == Thread.currentThread()) {
+ throw new CoordinationException(Messages.CoordinationImpl_1, CoordinationImpl.this, CoordinationException.DEADLOCK_DETECTED);
+ }
+ }
+ }
+ // The participant is already participating in another coordination
+ // that's not using this thread. Block until that coordination has
+ // finished. A decision was made here to use a timeout and incur the
+ // expense of waking up and rejoining in order to make a reasonably
+ // timely exit if this coordination terminates.
+ try {
+ coordination.join(1000);
+ } catch (InterruptedException e) {
+ coordinator.getLogService().log(LogService.LOG_DEBUG, Messages.CoordinationImpl_2, e);
+ // This thread was interrupted while waiting for the coordination
+ // to terminate.
+ throw new CoordinationException(Messages.CoordinationImpl_3, CoordinationImpl.this, CoordinationException.LOCK_INTERRUPTED, e);
+ }
+ }
+ }
+
+ public void end() throws CoordinationException {
+ coordinator.checkPermission(CoordinationPermission.INITIATE, name);
+ // Terminating the coordination must be atomic.
+ synchronized (this) {
+ // If this coordination is associated with a thread, an additional
+ // check is required.
+ if (thread != null) {
+ // Coordinations may only be ended by the same thread that
+ // pushed them onto the stack, if any.
+ if (thread != Thread.currentThread()) {
+ throw new CoordinationException(Messages.CoordinationImpl_14, this, CoordinationException.WRONG_THREAD);
+ }
+ // Unwind the stack in case there are other coordinations higher
+ // up than this one.
+ while (coordinator.peek() != this) {
+ try {
+ coordinator.peek().end();
+ } catch (CoordinationException e) {
+ coordinator.peek().fail(e);
+ }
+ }
+ // A coordination is removed from the thread local stack only when being ended.
+ // This must occur even if the coordination is already terminated due to a
+ // failure.
+ coordinator.pop();
+ }
+ terminate();
+ }
+ // Notify participants this coordination has ended. Track whether or
+ // not a partial ending has occurred.
+ Exception exception = null;
+ // No additional synchronization is needed here because the participant
+ // list will not be modified post termination.
+ for (Participant participant : participants) {
+ try {
+ participant.ended(this);
+ } catch (Exception e) {
+ coordinator.getLogService().log(LogService.LOG_WARNING, Messages.CoordinationImpl_4, e);
+ // Only the first exception will be propagated.
+ if (exception == null)
+ exception = e;
+ }
+ }
+ synchronized (this) {
+ // Notify everything joined to this coordination that it has finished.
+ notifyAll();
+ }
+ // If a partial ending has occurred, throw the required exception.
+ if (exception != null) {
+ throw new CoordinationException(Messages.CoordinationImpl_5, this, CoordinationException.PARTIALLY_ENDED, exception);
+ }
+ }
+
+ public long extendTimeout(long timeInMillis) throws CoordinationException {
+ coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
+ validateTimeout(timeInMillis);
+ // We don't want this coordination to terminate before the new timer is
+ // in place.
+ synchronized (this) {
+ // Check to see if this coordination has already terminated. If so,
+ // throw the appropriate exception.
+ checkTerminated();
+ // If there was no previous timeout set, return 0 indicating that no
+ // extension has taken place.
+ if (timerTask == null)
+ return 0;
+ // Passing anything less than zero as well as zero itself will return the
+ // existing deadline. The deadline will not be null if timerTask is not null.
+ if (timeInMillis == 0)
+ return deadline.getTime();
+ // Cancel the current timeout.
+ boolean cancelled = timerTask.cancel();
+ if (!cancelled) {
+ // This means the previous task has run and is waiting to get a lock on
+ // this coordination. We can't throw an exception yet because we can't
+ // know which one to use (ALREADY_ENDED or FAILED). Once the lock is
+ // released, the running task may fail this coordination due to a timeout,
+ // or something else might be waiting to fail this coordination for other
+ // reasons or to end it. We simply don't know who will win the race.
+ try {
+ // Wait until this coordination terminates.
+ join(0);
+ // Now determine how it terminated and throw the appropriate exception.
+ checkTerminated();
+ }
+ catch (InterruptedException e) {
+ throw new CoordinationException(Messages.CoordinationImpl_13, this, CoordinationException.UNKNOWN, e);
+ }
+ }
+ // Create the new timeout.
+ timerTask = new CoordinationTimerTask(this);
+ // Extend the current deadline.
+ deadline = new Date(deadline.getTime() + timeInMillis);
+ // Schedule the new timeout.
+ coordinator.schedule(timerTask, deadline);
+ // Return the new deadline.
+ return deadline.getTime();
+ }
+ }
+
+ public boolean fail(Throwable reason) {
+ coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
+ // The reason must not be null.
+ if (reason == null)
+ throw new NullPointerException(Messages.CoordinationImpl_11);
+ // Terminating the coordination must be atomic.
+ synchronized (this) {
+ // If this coordination is terminated, return false. Do not throw a
+ // CoordinationException as in other methods.
+ if (terminated)
+ return false;
+ // This coordination has not already terminated, so terminate now.
+ terminate();
+ // Store the reason for the failure.
+ failure = reason;
+ }
+ // Notify participants this coordination has failed.
+ // No additional synchronization is needed here because the participant
+ // list will not be modified post termination.
+ for (Participant participant : participants) {
+ try {
+ participant.failed(this);
+ } catch (Exception e) {
+ coordinator.getLogService().log(LogService.LOG_WARNING, Messages.CoordinationImpl_6, e);
+ }
+ }
+ synchronized (this) {
+ // Notify everything joined to this coordination that it has finished.
+ notifyAll();
+ }
+ // Return true to indicate this call resulted in the coordination's failure.
+ return true;
+ }
+
+ public Bundle getBundle() {
+ coordinator.checkPermission(CoordinationPermission.ADMIN, name);
+ return coordinator.getBundle();
+ }
+
+ public synchronized Coordination getEnclosingCoordination() {
+ coordinator.checkPermission(CoordinationPermission.ADMIN, name);
+ return enclosingCoordination == null ? null : enclosingCoordination.get();
+ }
+
+ public Throwable getFailure() {
+ coordinator.checkPermission(CoordinationPermission.INITIATE, name);
+ return failure;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public List<Participant> getParticipants() {
+ // This method requires the ADMIN permission.
+ coordinator.checkPermission(CoordinationPermission.INITIATE, name);
+ // Return a mutable snapshot.
+ synchronized (participants) {
+ return new ArrayList<Participant>(participants);
+ }
+ }
+
+ public synchronized Thread getThread() {
+ coordinator.checkPermission(CoordinationPermission.ADMIN, name);
+ return thread;
+ }
+
+ public Map<Class<?>, Object> getVariables() {
+ coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
+ return variables;
+ }
+
+ public boolean isTerminated() {
+ return terminated;
+ }
+
+ public void join(long timeInMillis) throws InterruptedException {
+ coordinator.checkPermission(CoordinationPermission.PARTICIPATE, name);
+ long start = System.currentTimeMillis();
+ // Wait until this coordination has terminated. Guard against spurious
+ // wakeups using isTerminated().
+ synchronized (this) {
+ while (!terminated) {
+ wait(timeInMillis);
+ long elapsed = System.currentTimeMillis() - start;
+ if (elapsed > timeInMillis)
+ break;
+ }
+ }
+ }
+
+ public Coordination push() throws CoordinationException {
+ coordinator.checkPermission(CoordinationPermission.INITIATE, name);
+ synchronized (this) {
+ checkTerminated();
+ coordinator.push(this);
+ }
+ return this;
+ }
+
+ synchronized Date getDeadline() {
+ return deadline;
+ }
+
+ LogService getLogService() {
+ return coordinator.getLogService();
+ }
+
+ synchronized void setTimerTask(TimerTask timerTask) {
+ this.timerTask = timerTask;
+ }
+
+ synchronized void setThreadAndEnclosingCoordination(Thread t, Reference<CoordinationImpl> c) {
+ thread = t;
+ enclosingCoordination = c;
+ }
+
+ private void checkTerminated() throws CoordinationException {
+ // If this coordination is not terminated, simply return.
+ if (!terminated)
+ return;
+ // The coordination has terminated. Figure out which type of exception
+ // must be thrown.
+ if (failure != null) {
+ // The fail() method was called indicating the coordination failed.
+ throw new CoordinationException(Messages.CoordinationImpl_7, this, CoordinationException.FAILED, failure);
+ }
+ // The coordination did not fail, so it either partially ended or
+ // ended successfully.
+ throw new CoordinationException(Messages.CoordinationImpl_8, CoordinationImpl.this, CoordinationException.ALREADY_ENDED);
+ }
+
+ private void terminate() throws CoordinationException {
+ checkTerminated();
+ terminated = true;
+ // Cancel the timeout. Purge the task if it was, in fact, canceled.
+ if (timerTask != null && timerTask.cancel()) {
+ coordinator.purge();
+ }
+ coordinator.terminate(this, participants);
+ }
+
+ private static void validateName(String name) {
+ boolean valid = true;
+ if (name == null || name.length() == 0)
+ valid = false;
+ else {
+ boolean period = false;
+ for (char c : name.toCharArray()) {
+ if (Character.isLetterOrDigit(c) || c == '_' || c == '-') {
+ period = false;
+ } else if (c == '.' && !period) {
+ period = true;
+ } else {
+ valid = false;
+ break;
+ }
+ }
+ }
+ if (!valid)
+ throw new IllegalArgumentException(Messages.CoordinationImpl_10);
+ }
+
+ private static void validateTimeout(long timeout) {
+ if (timeout < 0)
+ throw new IllegalArgumentException(Messages.CoordinationImpl_12);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationTimerTask.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationTimerTask.java
index 6f3279fa4..8c243d3f5 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationTimerTask.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationTimerTask.java
@@ -1,37 +1,37 @@
-/*******************************************************************************
- * Copyright (c) 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
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.coordinator;
-
-import java.util.TimerTask;
-
-import org.osgi.service.coordinator.Coordination;
-import org.osgi.service.log.LogService;
-
-public class CoordinationTimerTask extends TimerTask {
- private final CoordinationImpl coordination;
-
- public CoordinationTimerTask(CoordinationImpl coordination) {
- if (coordination == null)
- throw new IllegalArgumentException(Messages.CoordinationImpl_0);
- this.coordination = coordination;
- }
-
- @Override
- public void run() {
- // Catch all exceptions and errors in order to prevent the timer
- // thread from stopping.
- try {
- coordination.fail(Coordination.TIMEOUT);
- } catch (Throwable t) {
- coordination.getLogService().log(LogService.LOG_ERROR, Messages.CoordinationImpl_9, t);
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import java.util.TimerTask;
+
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.log.LogService;
+
+public class CoordinationTimerTask extends TimerTask {
+ private final CoordinationImpl coordination;
+
+ public CoordinationTimerTask(CoordinationImpl coordination) {
+ if (coordination == null)
+ throw new IllegalArgumentException(Messages.CoordinationImpl_0);
+ this.coordination = coordination;
+ }
+
+ @Override
+ public void run() {
+ // Catch all exceptions and errors in order to prevent the timer
+ // thread from stopping.
+ try {
+ coordination.fail(Coordination.TIMEOUT);
+ } catch (Throwable t) {
+ coordination.getLogService().log(LogService.LOG_ERROR, Messages.CoordinationImpl_9, t);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorComponent.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorComponent.java
index a03b311a8..31b8e3e33 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorComponent.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorComponent.java
@@ -1,64 +1,64 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 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.equinox.coordinator;
-
-import java.util.Collection;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.coordinator.Coordination;
-import org.osgi.service.coordinator.CoordinationException;
-import org.osgi.service.coordinator.Coordinator;
-import org.osgi.service.coordinator.Participant;
-
-public class CoordinatorComponent implements Coordinator {
- private volatile Coordinator coordinator;
-
- public boolean addParticipant(Participant participant) throws CoordinationException {
- return coordinator.addParticipant(participant);
- }
-
- public Coordination begin(String name, long timeout) {
- return coordinator.begin(name, timeout);
- }
-
- public Coordination create(String name, long timeout) {
- return coordinator.create(name, timeout);
- }
-
- public boolean fail(Throwable reason) {
- return coordinator.fail(reason);
- }
-
- public Coordination getCoordination(long id) {
- return coordinator.getCoordination(id);
- }
-
- public Collection<Coordination> getCoordinations() {
- return coordinator.getCoordinations();
- }
-
- public Coordination peek() {
- return coordinator.peek();
- }
-
- public Coordination pop() {
- return coordinator.pop();
- }
-
- void activate(ComponentContext componentContext) {
- coordinator = Activator.factory.getService(componentContext.getUsingBundle(), null);
- }
-
- void deactivate(BundleContext context) {
- ((CoordinatorImpl) coordinator).shutdown();
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import java.util.Collection;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.CoordinationException;
+import org.osgi.service.coordinator.Coordinator;
+import org.osgi.service.coordinator.Participant;
+
+public class CoordinatorComponent implements Coordinator {
+ private volatile Coordinator coordinator;
+
+ public boolean addParticipant(Participant participant) throws CoordinationException {
+ return coordinator.addParticipant(participant);
+ }
+
+ public Coordination begin(String name, long timeout) {
+ return coordinator.begin(name, timeout);
+ }
+
+ public Coordination create(String name, long timeout) {
+ return coordinator.create(name, timeout);
+ }
+
+ public boolean fail(Throwable reason) {
+ return coordinator.fail(reason);
+ }
+
+ public Coordination getCoordination(long id) {
+ return coordinator.getCoordination(id);
+ }
+
+ public Collection<Coordination> getCoordinations() {
+ return coordinator.getCoordinations();
+ }
+
+ public Coordination peek() {
+ return coordinator.peek();
+ }
+
+ public Coordination pop() {
+ return coordinator.pop();
+ }
+
+ void activate(ComponentContext componentContext) {
+ coordinator = Activator.factory.getService(componentContext.getUsingBundle(), null);
+ }
+
+ void deactivate(BundleContext context) {
+ ((CoordinatorImpl) coordinator).shutdown();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java
index e89be7d24..4060b66b4 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java
@@ -1,292 +1,292 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 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.equinox.coordinator;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.security.Permission;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.osgi.framework.Bundle;
-import org.osgi.service.coordinator.Coordination;
-import org.osgi.service.coordinator.CoordinationException;
-import org.osgi.service.coordinator.CoordinationPermission;
-import org.osgi.service.coordinator.Coordinator;
-import org.osgi.service.coordinator.Participant;
-import org.osgi.service.log.LogService;
-
-public class CoordinatorImpl implements Coordinator {
- // IDs must be positive integers and monotonically increasing.
- private static long lastId;
-
- private synchronized static long getNextId() {
- if (Long.MAX_VALUE == lastId)
- throw new IllegalStateException(Messages.CoordinatorImpl_0);
- // First ID will be 1.
- return ++lastId;
- }
-
- // Coordination IDs must be unique across all using bundles.
- private static final Map<Long, CoordinationImpl> idToCoordination = new HashMap<Long, CoordinationImpl>();
- // Coordination participation must be tracked across all using bundles.
- private static final Map<Participant, CoordinationImpl> participantToCoordination = new IdentityHashMap<Participant, CoordinationImpl>();
-
- private static ThreadLocal<WeakCoordinationStack> coordinationStack = new ThreadLocal<WeakCoordinationStack>() {
- @Override
- protected WeakCoordinationStack initialValue() {
- return new WeakCoordinationStack();
- }
- };
-
- private static class WeakCoordinationStack {
- private final LinkedList<Reference<CoordinationImpl>> coordinations = new LinkedList<Reference<CoordinationImpl>>();
- private final ReferenceQueue<CoordinationImpl> queue = new ReferenceQueue<CoordinationImpl>();
-
- public WeakCoordinationStack() {
- }
-
- public boolean contains(CoordinationImpl c) {
- purge();
- for (Reference<CoordinationImpl> r : coordinations) {
- if (c.equals(r.get()))
- return true;
- }
- return false;
- }
-
- public CoordinationImpl peek() {
- purge();
- if (coordinations.isEmpty())
- return null;
- return coordinations.getFirst().get();
- }
-
- public CoordinationImpl pop() {
- purge();
- if (coordinations.isEmpty())
- return null;
- CoordinationImpl c = coordinations.removeFirst().get();
- if (c != null)
- c.setThreadAndEnclosingCoordination(null, null);
- return c;
- }
-
- public void push(CoordinationImpl c) {
- purge();
- if (contains(c))
- throw new CoordinationException(Messages.CoordinatorImpl_3, c, CoordinationException.ALREADY_PUSHED);
- Reference<CoordinationImpl> r = new WeakReference<CoordinationImpl>(c, queue);
- c.setThreadAndEnclosingCoordination(Thread.currentThread(), coordinations.isEmpty() ? null : coordinations.getFirst());
- coordinations.addFirst(r);
- }
-
- private void purge() {
- Reference<? extends CoordinationImpl> r;
- while ((r = queue.poll()) != null) {
- int index = coordinations.indexOf(r);
- coordinations.remove(r);
- if (index > 0) {
- r = coordinations.get(index - 1);
- CoordinationImpl c = r.get();
- if (c != null)
- c.setThreadAndEnclosingCoordination(Thread.currentThread(), coordinations.get(index));
- }
- }
- }
- }
-
- private final Bundle bundle;
- private final List<CoordinationImpl> coordinations;
- private final LogService logService;
- private final Timer timer;
-
- private boolean shutdown;
-
- public CoordinatorImpl(Bundle bundle, LogService logService, Timer timer) {
- this.bundle = bundle;
- this.logService = logService;
- this.timer = timer;
- coordinations = new ArrayList<CoordinationImpl>();
- }
-
- public boolean addParticipant(Participant participant) throws CoordinationException {
- Coordination coordination = peek();
- if (coordination == null)
- return false;
- coordination.addParticipant(participant);
- return true;
- }
-
- public Coordination begin(String name, long timeout) {
- CoordinationImpl coordination = (CoordinationImpl) create(name, timeout);
- coordination.push();
- return coordination;
- }
-
- public Coordination create(String name, long timeout) {
- // This method requires the INITIATE permission. No bundle check is done.
- checkPermission(CoordinationPermission.INITIATE, name);
- CoordinationImpl coordination = new CoordinationImpl(getNextId(), name, timeout, this);
- synchronized (this) {
- if (shutdown)
- throw new IllegalStateException(Messages.CoordinatorImpl_2);
- synchronized (CoordinatorImpl.class) {
- coordinations.add(coordination);
- idToCoordination.put(new Long(coordination.getId()), coordination);
- }
- }
- if (timeout > 0) {
- TimerTask timerTask = new CoordinationTimerTask(coordination);
- coordination.setTimerTask(timerTask);
- schedule(timerTask, coordination.getDeadline());
- }
- return coordination;
- }
-
- public boolean fail(Throwable reason) {
- Coordination coordination = peek();
- if (coordination == null)
- return false;
- return coordination.fail(reason);
- }
-
- public Coordination getCoordination(long id) {
- CoordinationImpl result = null;
- synchronized (CoordinatorImpl.class) {
- result = idToCoordination.get(new Long(id));
- }
- if (result != null && !result.isTerminated()) {
- try {
- checkPermission(CoordinationPermission.ADMIN, result.getName());
- } catch (SecurityException e) {
- logService.log(LogService.LOG_DEBUG, Messages.CoordinatorImpl_1, e);
- result = null;
- }
- }
- return result;
- }
-
- public Collection<Coordination> getCoordinations() {
- ArrayList<Coordination> result;
- synchronized (CoordinatorImpl.class) {
- result = new ArrayList<Coordination>(idToCoordination.size());
- for (CoordinationImpl coordination : idToCoordination.values()) {
- // Ideally, we're only interested in coordinations that have not terminated.
- // It's okay, however, if the coordination terminates from this point forward.
- if (coordination.isTerminated())
- continue;
- try {
- checkPermission(CoordinationPermission.ADMIN, coordination.getName());
- result.add(coordination);
- } catch (SecurityException e) {
- logService.log(LogService.LOG_DEBUG, Messages.CoordinatorImpl_1, e);
- }
- }
- }
- result.trimToSize();
- return result;
- }
-
- public Coordination peek() {
- return coordinationStack.get().peek();
- }
-
- public Coordination pop() {
- Coordination c = coordinationStack.get().peek();
- if (c == null) return null;
- checkPermission(CoordinationPermission.INITIATE, c.getName());
- return coordinationStack.get().pop();
- }
-
- CoordinationImpl addParticipant(Participant participant, CoordinationImpl coordination) {
- CoordinationImpl result = null;
- synchronized (participantToCoordination) {
- result = participantToCoordination.get(participant);
- if (result == null) {
- participantToCoordination.put(participant, coordination);
- }
- }
- return result;
- }
-
- void checkPermission(String permissionType, String coordinationName) {
- checkPermission(new CoordinationPermission(coordinationName, bundle, permissionType));
- }
-
- void checkPermission(Permission permission) {
- SecurityManager securityManager = System.getSecurityManager();
- if (securityManager == null)
- return;
- securityManager.checkPermission(permission);
- }
-
- Bundle getBundle() {
- return bundle;
- }
-
- LogService getLogService() {
- return logService;
- }
-
- void purge() {
- // Purge the timer of all canceled tasks if we're running on a supportive JCL.
- try {
- Timer.class.getMethod("purge", (Class<?>[]) null).invoke(timer, (Object[]) null); //$NON-NLS-1$
- } catch (Exception e) {
- logService.log(LogService.LOG_DEBUG, Messages.CoordinatorImpl_4, e);
- }
- }
-
- void push(CoordinationImpl coordination) throws CoordinationException {
- coordinationStack.get().push(coordination);
- }
-
- void schedule(TimerTask task, Date deadline) {
- timer.schedule(task, deadline);
- }
-
- void shutdown() {
- List<Coordination> coords;
- synchronized (this) {
- shutdown = true;
- // Make a copy so the removal of the coordination from the list during
- // termination does not interfere with the iteration.
- coords = new ArrayList<Coordination>(this.coordinations);
- }
- for (Coordination coordination : coords) {
- coordination.fail(Coordination.RELEASED);
- }
- }
-
- /*
- * This procedure must occur when a coordination is being failed or ended.
- */
- void terminate(Coordination coordination, List<Participant> participants) {
- // A coordination has been terminated and needs to be removed from the thread local stack.
- synchronized (this) {
- synchronized (CoordinatorImpl.class) {
- this.coordinations.remove(coordination);
- idToCoordination.remove(new Long(coordination.getId()));
- participantToCoordination.keySet().removeAll(participants);
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.CoordinationException;
+import org.osgi.service.coordinator.CoordinationPermission;
+import org.osgi.service.coordinator.Coordinator;
+import org.osgi.service.coordinator.Participant;
+import org.osgi.service.log.LogService;
+
+public class CoordinatorImpl implements Coordinator {
+ // IDs must be positive integers and monotonically increasing.
+ private static long lastId;
+
+ private synchronized static long getNextId() {
+ if (Long.MAX_VALUE == lastId)
+ throw new IllegalStateException(Messages.CoordinatorImpl_0);
+ // First ID will be 1.
+ return ++lastId;
+ }
+
+ // Coordination IDs must be unique across all using bundles.
+ private static final Map<Long, CoordinationImpl> idToCoordination = new HashMap<Long, CoordinationImpl>();
+ // Coordination participation must be tracked across all using bundles.
+ private static final Map<Participant, CoordinationImpl> participantToCoordination = new IdentityHashMap<Participant, CoordinationImpl>();
+
+ private static ThreadLocal<WeakCoordinationStack> coordinationStack = new ThreadLocal<WeakCoordinationStack>() {
+ @Override
+ protected WeakCoordinationStack initialValue() {
+ return new WeakCoordinationStack();
+ }
+ };
+
+ private static class WeakCoordinationStack {
+ private final LinkedList<Reference<CoordinationImpl>> coordinations = new LinkedList<Reference<CoordinationImpl>>();
+ private final ReferenceQueue<CoordinationImpl> queue = new ReferenceQueue<CoordinationImpl>();
+
+ public WeakCoordinationStack() {
+ }
+
+ public boolean contains(CoordinationImpl c) {
+ purge();
+ for (Reference<CoordinationImpl> r : coordinations) {
+ if (c.equals(r.get()))
+ return true;
+ }
+ return false;
+ }
+
+ public CoordinationImpl peek() {
+ purge();
+ if (coordinations.isEmpty())
+ return null;
+ return coordinations.getFirst().get();
+ }
+
+ public CoordinationImpl pop() {
+ purge();
+ if (coordinations.isEmpty())
+ return null;
+ CoordinationImpl c = coordinations.removeFirst().get();
+ if (c != null)
+ c.setThreadAndEnclosingCoordination(null, null);
+ return c;
+ }
+
+ public void push(CoordinationImpl c) {
+ purge();
+ if (contains(c))
+ throw new CoordinationException(Messages.CoordinatorImpl_3, c, CoordinationException.ALREADY_PUSHED);
+ Reference<CoordinationImpl> r = new WeakReference<CoordinationImpl>(c, queue);
+ c.setThreadAndEnclosingCoordination(Thread.currentThread(), coordinations.isEmpty() ? null : coordinations.getFirst());
+ coordinations.addFirst(r);
+ }
+
+ private void purge() {
+ Reference<? extends CoordinationImpl> r;
+ while ((r = queue.poll()) != null) {
+ int index = coordinations.indexOf(r);
+ coordinations.remove(r);
+ if (index > 0) {
+ r = coordinations.get(index - 1);
+ CoordinationImpl c = r.get();
+ if (c != null)
+ c.setThreadAndEnclosingCoordination(Thread.currentThread(), coordinations.get(index));
+ }
+ }
+ }
+ }
+
+ private final Bundle bundle;
+ private final List<CoordinationImpl> coordinations;
+ private final LogService logService;
+ private final Timer timer;
+
+ private boolean shutdown;
+
+ public CoordinatorImpl(Bundle bundle, LogService logService, Timer timer) {
+ this.bundle = bundle;
+ this.logService = logService;
+ this.timer = timer;
+ coordinations = new ArrayList<CoordinationImpl>();
+ }
+
+ public boolean addParticipant(Participant participant) throws CoordinationException {
+ Coordination coordination = peek();
+ if (coordination == null)
+ return false;
+ coordination.addParticipant(participant);
+ return true;
+ }
+
+ public Coordination begin(String name, long timeout) {
+ CoordinationImpl coordination = (CoordinationImpl) create(name, timeout);
+ coordination.push();
+ return coordination;
+ }
+
+ public Coordination create(String name, long timeout) {
+ // This method requires the INITIATE permission. No bundle check is done.
+ checkPermission(CoordinationPermission.INITIATE, name);
+ CoordinationImpl coordination = new CoordinationImpl(getNextId(), name, timeout, this);
+ synchronized (this) {
+ if (shutdown)
+ throw new IllegalStateException(Messages.CoordinatorImpl_2);
+ synchronized (CoordinatorImpl.class) {
+ coordinations.add(coordination);
+ idToCoordination.put(new Long(coordination.getId()), coordination);
+ }
+ }
+ if (timeout > 0) {
+ TimerTask timerTask = new CoordinationTimerTask(coordination);
+ coordination.setTimerTask(timerTask);
+ schedule(timerTask, coordination.getDeadline());
+ }
+ return coordination;
+ }
+
+ public boolean fail(Throwable reason) {
+ Coordination coordination = peek();
+ if (coordination == null)
+ return false;
+ return coordination.fail(reason);
+ }
+
+ public Coordination getCoordination(long id) {
+ CoordinationImpl result = null;
+ synchronized (CoordinatorImpl.class) {
+ result = idToCoordination.get(new Long(id));
+ }
+ if (result != null && !result.isTerminated()) {
+ try {
+ checkPermission(CoordinationPermission.ADMIN, result.getName());
+ } catch (SecurityException e) {
+ logService.log(LogService.LOG_DEBUG, Messages.CoordinatorImpl_1, e);
+ result = null;
+ }
+ }
+ return result;
+ }
+
+ public Collection<Coordination> getCoordinations() {
+ ArrayList<Coordination> result;
+ synchronized (CoordinatorImpl.class) {
+ result = new ArrayList<Coordination>(idToCoordination.size());
+ for (CoordinationImpl coordination : idToCoordination.values()) {
+ // Ideally, we're only interested in coordinations that have not terminated.
+ // It's okay, however, if the coordination terminates from this point forward.
+ if (coordination.isTerminated())
+ continue;
+ try {
+ checkPermission(CoordinationPermission.ADMIN, coordination.getName());
+ result.add(coordination);
+ } catch (SecurityException e) {
+ logService.log(LogService.LOG_DEBUG, Messages.CoordinatorImpl_1, e);
+ }
+ }
+ }
+ result.trimToSize();
+ return result;
+ }
+
+ public Coordination peek() {
+ return coordinationStack.get().peek();
+ }
+
+ public Coordination pop() {
+ Coordination c = coordinationStack.get().peek();
+ if (c == null) return null;
+ checkPermission(CoordinationPermission.INITIATE, c.getName());
+ return coordinationStack.get().pop();
+ }
+
+ CoordinationImpl addParticipant(Participant participant, CoordinationImpl coordination) {
+ CoordinationImpl result = null;
+ synchronized (participantToCoordination) {
+ result = participantToCoordination.get(participant);
+ if (result == null) {
+ participantToCoordination.put(participant, coordination);
+ }
+ }
+ return result;
+ }
+
+ void checkPermission(String permissionType, String coordinationName) {
+ checkPermission(new CoordinationPermission(coordinationName, bundle, permissionType));
+ }
+
+ void checkPermission(Permission permission) {
+ SecurityManager securityManager = System.getSecurityManager();
+ if (securityManager == null)
+ return;
+ securityManager.checkPermission(permission);
+ }
+
+ Bundle getBundle() {
+ return bundle;
+ }
+
+ LogService getLogService() {
+ return logService;
+ }
+
+ void purge() {
+ // Purge the timer of all canceled tasks if we're running on a supportive JCL.
+ try {
+ Timer.class.getMethod("purge", (Class<?>[]) null).invoke(timer, (Object[]) null); //$NON-NLS-1$
+ } catch (Exception e) {
+ logService.log(LogService.LOG_DEBUG, Messages.CoordinatorImpl_4, e);
+ }
+ }
+
+ void push(CoordinationImpl coordination) throws CoordinationException {
+ coordinationStack.get().push(coordination);
+ }
+
+ void schedule(TimerTask task, Date deadline) {
+ timer.schedule(task, deadline);
+ }
+
+ void shutdown() {
+ List<Coordination> coords;
+ synchronized (this) {
+ shutdown = true;
+ // Make a copy so the removal of the coordination from the list during
+ // termination does not interfere with the iteration.
+ coords = new ArrayList<Coordination>(this.coordinations);
+ }
+ for (Coordination coordination : coords) {
+ coordination.fail(Coordination.RELEASED);
+ }
+ }
+
+ /*
+ * This procedure must occur when a coordination is being failed or ended.
+ */
+ void terminate(Coordination coordination, List<Participant> participants) {
+ // A coordination has been terminated and needs to be removed from the thread local stack.
+ synchronized (this) {
+ synchronized (CoordinatorImpl.class) {
+ this.coordinations.remove(coordination);
+ idToCoordination.remove(new Long(coordination.getId()));
+ participantToCoordination.keySet().removeAll(participants);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java
index 7dbe3f8f7..86dee1999 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java
@@ -1,42 +1,42 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 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.equinox.coordinator;
-
-import java.util.Timer;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.coordinator.Coordinator;
-
-public class CoordinatorServiceFactory implements ServiceFactory<Coordinator> {
- private final LogTracker logTracker;
- private final Timer timer = new Timer(true);
-
- public CoordinatorServiceFactory(BundleContext bundleContext) {
- logTracker = new LogTracker(bundleContext, System.out);
- }
-
- public Coordinator getService(Bundle bundle, ServiceRegistration<Coordinator> registration) {
- return new CoordinatorImpl(bundle, logTracker, timer);
- }
-
- public void ungetService(Bundle bundle, ServiceRegistration<Coordinator> registration, Coordinator service) {
- ((CoordinatorImpl) service).shutdown();
- }
-
- void shutdown() {
- timer.cancel();
-// CoordinatorImpl.reset();
- logTracker.close();
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import java.util.Timer;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.coordinator.Coordinator;
+
+public class CoordinatorServiceFactory implements ServiceFactory<Coordinator> {
+ private final LogTracker logTracker;
+ private final Timer timer = new Timer(true);
+
+ public CoordinatorServiceFactory(BundleContext bundleContext) {
+ logTracker = new LogTracker(bundleContext, System.out);
+ }
+
+ public Coordinator getService(Bundle bundle, ServiceRegistration<Coordinator> registration) {
+ return new CoordinatorImpl(bundle, logTracker, timer);
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration<Coordinator> registration, Coordinator service) {
+ ((CoordinatorImpl) service).shutdown();
+ }
+
+ void shutdown() {
+ timer.cancel();
+// CoordinatorImpl.reset();
+ logTracker.close();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogMessages.properties b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogMessages.properties
index 825f115ff..55d478416 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogMessages.properties
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogMessages.properties
@@ -1,17 +1,17 @@
-###############################################################################
-# Copyright (c) 2005, 2008 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
-###############################################################################
-# NLS_MESSAGEFORMAT_ALL
-
-Unknown_Log_level=Unknown Log Level
-Info=Log Info
-Warning=Log Warning
-Error=Log Error
-Debug=Log Debug
+###############################################################################
+# Copyright (c) 2005, 2011 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
+###############################################################################
+# NLS_MESSAGEFORMAT_ALL
+
+Unknown_Log_level=Unknown Log Level
+Info=Log Info
+Warning=Log Warning
+Error=Log Error
+Debug=Log Debug
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTracker.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTracker.java
index 427cae73b..2bd60a051 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTracker.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTracker.java
@@ -1,175 +1,175 @@
-/*******************************************************************************
- * Copyright (c) 1998, 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
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.coordinator;
-
-import java.io.PrintStream;
-import java.util.Calendar;
-import java.util.Date;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.log.LogService;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * LogTracker class. This class encapsulates the LogService
- * and handles all issues such as the service coming and going.
- */
-
-public class LogTracker extends ServiceTracker<LogService, LogService> implements LogService {
- /** LogService interface class name */
- protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$
-
- /** PrintStream to use if LogService is unavailable */
- private final PrintStream out;
-
- /**
- * Create new LogTracker.
- *
- * @param context BundleContext of parent bundle.
- * @param out Default PrintStream to use if LogService is unavailable.
- */
- public LogTracker(BundleContext context, PrintStream out) {
- super(context, clazz, null);
- this.out = out;
- }
-
- /*
- * ----------------------------------------------------------------------
- * LogService Interface implementation
- * ----------------------------------------------------------------------
- */
-
- public void log(int level, String message) {
- log(null, level, message, null);
- }
-
- public void log(int level, String message, Throwable exception) {
- log(null, level, message, exception);
- }
-
- public void log(@SuppressWarnings("rawtypes")
- ServiceReference reference, int level, String message) {
- log(reference, level, message, null);
- }
-
- public synchronized void log(@SuppressWarnings("rawtypes")
- ServiceReference reference, int level, String message, Throwable exception) {
- ServiceReference<LogService>[] references = getServiceReferences();
-
- if (references != null) {
- int size = references.length;
-
- for (int i = 0; i < size; i++) {
- LogService service = getService(references[i]);
- if (service != null) {
- try {
- service.log(reference, level, message, exception);
- } catch (Exception e) {
- // TODO: consider printing to System Error
- }
- }
- }
-
- return;
- }
-
- noLogService(level, message, exception, reference);
- }
-
- /**
- * The LogService is not available so we write the message to a PrintStream.
- *
- * @param level Logging level
- * @param message Log message.
- * @param throwable Log exception or null if none.
- * @param reference ServiceReference associated with message or null if none.
- */
- protected void noLogService(int level, String message, Throwable throwable, ServiceReference<?> reference) {
- if (out != null) {
- synchronized (out) {
- // Bug #113286. If no log service present and messages are being
- // printed to stdout, prepend message with a timestamp.
- String timestamp = getDate(new Date());
- out.print(timestamp + " "); //$NON-NLS-1$
-
- switch (level) {
- case LOG_DEBUG : {
- out.print(LogTrackerMsg.Debug);
-
- break;
- }
- case LOG_INFO : {
- out.print(LogTrackerMsg.Info);
-
- break;
- }
- case LOG_WARNING : {
- out.print(LogTrackerMsg.Warning);
-
- break;
- }
- case LOG_ERROR : {
- out.print(LogTrackerMsg.Error);
-
- break;
- }
- default : {
- out.print("["); //$NON-NLS-1$
- out.print(LogTrackerMsg.Unknown_Log_level);
- out.print("]: "); //$NON-NLS-1$
-
- break;
- }
- }
-
- out.println(message);
-
- if (reference != null) {
- out.println(reference);
- }
-
- if (throwable != null) {
- throwable.printStackTrace(out);
- }
- }
- }
- }
-
- // from EclipseLog to avoid using DateFormat -- see bug 149892#c10
- private String getDate(Date date) {
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- StringBuffer sb = new StringBuffer();
- appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
- appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
- appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
- appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
- appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
- appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
- appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
- return sb.toString();
- }
-
- private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
- pad = pad - 1;
- if (pad == 0)
- return buffer.append(Integer.toString(value));
- int padding = (int) Math.pow(10, pad);
- if (value >= padding)
- return buffer.append(Integer.toString(value));
- while (padding > value && padding > 1) {
- buffer.append('0');
- padding = padding / 10;
- }
- buffer.append(value);
- return buffer;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 1998, 2011 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.equinox.coordinator;
+
+import java.io.PrintStream;
+import java.util.Calendar;
+import java.util.Date;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * LogTracker class. This class encapsulates the LogService
+ * and handles all issues such as the service coming and going.
+ */
+
+public class LogTracker extends ServiceTracker<LogService, LogService> implements LogService {
+ /** LogService interface class name */
+ protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$
+
+ /** PrintStream to use if LogService is unavailable */
+ private final PrintStream out;
+
+ /**
+ * Create new LogTracker.
+ *
+ * @param context BundleContext of parent bundle.
+ * @param out Default PrintStream to use if LogService is unavailable.
+ */
+ public LogTracker(BundleContext context, PrintStream out) {
+ super(context, clazz, null);
+ this.out = out;
+ }
+
+ /*
+ * ----------------------------------------------------------------------
+ * LogService Interface implementation
+ * ----------------------------------------------------------------------
+ */
+
+ public void log(int level, String message) {
+ log(null, level, message, null);
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ log(null, level, message, exception);
+ }
+
+ public void log(@SuppressWarnings("rawtypes")
+ ServiceReference reference, int level, String message) {
+ log(reference, level, message, null);
+ }
+
+ public synchronized void log(@SuppressWarnings("rawtypes")
+ ServiceReference reference, int level, String message, Throwable exception) {
+ ServiceReference<LogService>[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ LogService service = getService(references[i]);
+ if (service != null) {
+ try {
+ service.log(reference, level, message, exception);
+ } catch (Exception e) {
+ // TODO: consider printing to System Error
+ }
+ }
+ }
+
+ return;
+ }
+
+ noLogService(level, message, exception, reference);
+ }
+
+ /**
+ * The LogService is not available so we write the message to a PrintStream.
+ *
+ * @param level Logging level
+ * @param message Log message.
+ * @param throwable Log exception or null if none.
+ * @param reference ServiceReference associated with message or null if none.
+ */
+ protected void noLogService(int level, String message, Throwable throwable, ServiceReference<?> reference) {
+ if (out != null) {
+ synchronized (out) {
+ // Bug #113286. If no log service present and messages are being
+ // printed to stdout, prepend message with a timestamp.
+ String timestamp = getDate(new Date());
+ out.print(timestamp + " "); //$NON-NLS-1$
+
+ switch (level) {
+ case LOG_DEBUG : {
+ out.print(LogTrackerMsg.Debug);
+
+ break;
+ }
+ case LOG_INFO : {
+ out.print(LogTrackerMsg.Info);
+
+ break;
+ }
+ case LOG_WARNING : {
+ out.print(LogTrackerMsg.Warning);
+
+ break;
+ }
+ case LOG_ERROR : {
+ out.print(LogTrackerMsg.Error);
+
+ break;
+ }
+ default : {
+ out.print("["); //$NON-NLS-1$
+ out.print(LogTrackerMsg.Unknown_Log_level);
+ out.print("]: "); //$NON-NLS-1$
+
+ break;
+ }
+ }
+
+ out.println(message);
+
+ if (reference != null) {
+ out.println(reference);
+ }
+
+ if (throwable != null) {
+ throwable.printStackTrace(out);
+ }
+ }
+ }
+ }
+
+ // from EclipseLog to avoid using DateFormat -- see bug 149892#c10
+ private String getDate(Date date) {
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ StringBuffer sb = new StringBuffer();
+ appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
+ appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
+ appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
+ appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
+ appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
+ appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
+ appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
+ return sb.toString();
+ }
+
+ private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
+ pad = pad - 1;
+ if (pad == 0)
+ return buffer.append(Integer.toString(value));
+ int padding = (int) Math.pow(10, pad);
+ if (value >= padding)
+ return buffer.append(Integer.toString(value));
+ while (padding > value && padding > 1) {
+ buffer.append('0');
+ padding = padding / 10;
+ }
+ buffer.append(value);
+ return buffer;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTrackerMsg.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTrackerMsg.java
index 412163feb..33ea3d0d1 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTrackerMsg.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/LogTrackerMsg.java
@@ -1,28 +1,28 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2008 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.equinox.coordinator;
-
-import org.eclipse.osgi.util.NLS;
-
-public class LogTrackerMsg extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.event.LogMessages"; //$NON-NLS-1$
-
- public static String Unknown_Log_level;
- public static String Info;
- public static String Warning;
- public static String Error;
- public static String Debug;
-
- static {
- // initialize resource bundles
- NLS.initializeMessages(BUNDLE_NAME, LogTrackerMsg.class);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 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.equinox.coordinator;
+
+import org.eclipse.osgi.util.NLS;
+
+public class LogTrackerMsg extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.event.LogMessages"; //$NON-NLS-1$
+
+ public static String Unknown_Log_level;
+ public static String Info;
+ public static String Warning;
+ public static String Error;
+ public static String Debug;
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, LogTrackerMsg.class);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java
index b70104e48..bb520588a 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java
@@ -1,47 +1,47 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 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.equinox.coordinator;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.equinox.coordinator.messages"; //$NON-NLS-1$
- public static String CoordinationImpl_0;
- public static String CoordinationImpl_1;
- public static String CoordinationImpl_10;
- public static String CoordinationImpl_11;
- public static String CoordinationImpl_12;
- public static String CoordinationImpl_13;
- public static String CoordinationImpl_14;
- public static String CoordinationImpl_15;
- public static String CoordinationImpl_2;
- public static String CoordinationImpl_3;
- public static String CoordinationImpl_4;
- public static String CoordinationImpl_5;
- public static String CoordinationImpl_6;
- public static String CoordinationImpl_7;
- public static String CoordinationImpl_8;
- public static String CoordinationImpl_9;
- public static String CoordinatorImpl_0;
- public static String CoordinatorImpl_1;
- public static String CoordinatorImpl_2;
- public static String CoordinatorImpl_3;
- public static String CoordinatorImpl_4;
-
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
-
- private Messages() {
- // noop
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 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.equinox.coordinator;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.coordinator.messages"; //$NON-NLS-1$
+ public static String CoordinationImpl_0;
+ public static String CoordinationImpl_1;
+ public static String CoordinationImpl_10;
+ public static String CoordinationImpl_11;
+ public static String CoordinationImpl_12;
+ public static String CoordinationImpl_13;
+ public static String CoordinationImpl_14;
+ public static String CoordinationImpl_15;
+ public static String CoordinationImpl_2;
+ public static String CoordinationImpl_3;
+ public static String CoordinationImpl_4;
+ public static String CoordinationImpl_5;
+ public static String CoordinationImpl_6;
+ public static String CoordinationImpl_7;
+ public static String CoordinationImpl_8;
+ public static String CoordinationImpl_9;
+ public static String CoordinatorImpl_0;
+ public static String CoordinatorImpl_1;
+ public static String CoordinatorImpl_2;
+ public static String CoordinatorImpl_3;
+ public static String CoordinatorImpl_4;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ // noop
+ }
+}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties
index 881973626..bf1e76e49 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties
@@ -1,31 +1,31 @@
-###############################################################################
-# Copyright (c) 2010, 2011 IBM Corporation.
-# 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
-###############################################################################
-CoordinationImpl_0=Parameter must not be null: coordination
-CoordinationImpl_1=Deadlock detected
-CoordinationImpl_10=The coordination name does not match the Bundle Symbolic Name pattern
-CoordinationImpl_11=A reason must be specified when failing a coordination
-CoordinationImpl_12=A timeout must be a non-negative integer
-CoordinationImpl_13=The timeout could not be extended because the previous one had already expired. The current thread was interrupted before it was possible to determine how this coordination terminated.
-CoordinationImpl_14=Coordinations may only be ended by the same thread that pushed them onto the thread local stack
-CoordinationImpl_15=The participant to add was null
-CoordinationImpl_2=The lock was interrupted
-CoordinationImpl_3=The lock was interrupted
-CoordinationImpl_4=A participant indicated an error occurred while the coordination was ending
-CoordinationImpl_5=Partially ended
-CoordinationImpl_6=A participant indicated an error occurred while the coordination was failing
-CoordinationImpl_7=Coordination has failed
-CoordinationImpl_8=Coordination has already ended
-CoordinationImpl_9=An unexpected exception occurred while failing a coordination. This will not stop the timer thread.
-CoordinatorImpl_0=The next Coordinator ID would exceed the maximum possible value
-CoordinatorImpl_1=A requestor did not have permission to view a coordination
-CoordinatorImpl_2=This coordinator has been shutdown
-CoordinatorImpl_3=Coordination already exists
-CoordinatorImpl_4=Unable to purge the canceled task
+###############################################################################
+# Copyright (c) 2010, 2011 IBM Corporation.
+# 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
+###############################################################################
+CoordinationImpl_0=Parameter must not be null: coordination
+CoordinationImpl_1=Deadlock detected
+CoordinationImpl_10=The coordination name does not match the Bundle Symbolic Name pattern
+CoordinationImpl_11=A reason must be specified when failing a coordination
+CoordinationImpl_12=A timeout must be a non-negative integer
+CoordinationImpl_13=The timeout could not be extended because the previous one had already expired. The current thread was interrupted before it was possible to determine how this coordination terminated.
+CoordinationImpl_14=Coordinations may only be ended by the same thread that pushed them onto the thread local stack
+CoordinationImpl_15=The participant to add was null
+CoordinationImpl_2=The lock was interrupted
+CoordinationImpl_3=The lock was interrupted
+CoordinationImpl_4=A participant indicated an error occurred while the coordination was ending
+CoordinationImpl_5=Partially ended
+CoordinationImpl_6=A participant indicated an error occurred while the coordination was failing
+CoordinationImpl_7=Coordination has failed
+CoordinationImpl_8=Coordination has already ended
+CoordinationImpl_9=An unexpected exception occurred while failing a coordination. This will not stop the timer thread.
+CoordinatorImpl_0=The next Coordinator ID would exceed the maximum possible value
+CoordinatorImpl_1=A requestor did not have permission to view a coordination
+CoordinatorImpl_2=This coordinator has been shutdown
+CoordinatorImpl_3=Coordination already exists
+CoordinatorImpl_4=Unable to purge the canceled task

Back to the top