diff options
author | Eike Stepper | 2016-01-10 10:27:48 +0000 |
---|---|---|
committer | Eike Stepper | 2016-01-12 07:00:26 +0000 |
commit | 11cdaee2b9ed25674935f4d7b7cdbc1d7a7abd53 (patch) | |
tree | a6b9c8e0852bc1ca780b7258ceab92d0631f62a2 | |
parent | c523e8929ec6285254f381732604edf5d32bc294 (diff) | |
download | cdo-11cdaee2b9ed25674935f4d7b7cdbc1d7a7abd53.tar.gz cdo-11cdaee2b9ed25674935f4d7b7cdbc1d7a7abd53.tar.xz cdo-11cdaee2b9ed25674935f4d7b7cdbc1d7a7abd53.zip |
[485491] Provide a logging facility for CDOViewEvents
https://bugs.eclipse.org/bugs/show_bug.cgi?id=485491
7 files changed, 694 insertions, 10 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/AbstractCDOViewProvider.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/AbstractCDOViewProvider.java index 5537f1df25..7662f2545a 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/AbstractCDOViewProvider.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/AbstractCDOViewProvider.java @@ -126,4 +126,10 @@ public abstract class AbstractCDOViewProvider implements CDOViewProvider2 { return uri.path(); } + + @Override + public String toString() + { + return "CDOViewProviderDescriptor[" + getPriority() + " --> " + getRegex() + "]"; + } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOViewEventProducer.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOViewEventProducer.java new file mode 100644 index 0000000000..cd536e3300 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOViewEventProducer.java @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2004-2015 Eike Stepper (Berlin, Germany) 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.view; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOState; +import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; +import org.eclipse.emf.cdo.transaction.CDOCommitContext; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.transaction.CDOTransactionHandler1; +import org.eclipse.emf.cdo.transaction.CDOTransactionHandler2; + +import org.eclipse.net4j.util.container.SelfAttachingContainerListener; +import org.eclipse.net4j.util.event.Event; +import org.eclipse.net4j.util.event.IListener; + +/** + * @author Eike Stepper + * @since 4.5 + */ +public class CDOViewEventProducer extends SelfAttachingContainerListener.Delegating +{ + private final CDOObjectHandler objectHandler = new CDOObjectHandler() + { + public void objectStateChanged(CDOView view, CDOObject object, CDOState oldState, CDOState newState) + { + notifyOtherEvent(new CDOObjectStateChangedEvent(view, object, oldState, newState)); + } + }; + + private final CDOTransactionHandler1 transactionHandler1 = new CDOTransactionHandler1() + { + public void attachingObject(CDOTransaction transaction, CDOObject object) + { + notifyOtherEvent(new CDOAttachingObjectEvent(transaction, object)); + } + + public void detachingObject(CDOTransaction transaction, CDOObject object) + { + notifyOtherEvent(new CDODetachingObjectEvent(transaction, object)); + } + + public void modifyingObject(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureDelta) + { + notifyOtherEvent(new CDOModifyingObjectEvent(transaction, object, featureDelta)); + } + }; + + private final CDOTransactionHandler2 transactionHandler2 = new CDOTransactionHandler2() + { + public void committingTransaction(CDOTransaction transaction, CDOCommitContext commitContext) + { + notifyOtherEvent(new CDOCommittingTransactionEvent(transaction, commitContext)); + } + + public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext) + { + notifyOtherEvent(new CDOCommittedTransactionEvent(transaction, commitContext)); + } + + public void rolledBackTransaction(CDOTransaction transaction) + { + notifyOtherEvent(new CDORolledBackTransactionEvent(transaction)); + } + }; + + public CDOViewEventProducer(IListener delegate, boolean delegateContainerEvents) + { + super(delegate, delegateContainerEvents); + } + + public CDOViewEventProducer(IListener delegate) + { + super(delegate); + } + + @Override + public void attach(Object element) + { + if (element instanceof CDOView) + { + CDOView view = (CDOView)element; + if (produceObjectStateChangedEvents()) + { + view.addObjectHandler(objectHandler); + } + + if (view instanceof CDOTransaction) + { + CDOTransaction transaction = (CDOTransaction)view; + if (produceObjectModificationEvents()) + { + transaction.addTransactionHandler(transactionHandler1); + } + + if (produceTransactionDemarcationEvents()) + { + transaction.addTransactionHandler(transactionHandler2); + } + } + } + + super.attach(element); + } + + @Override + public void detach(Object element) + { + super.detach(element); + + if (element instanceof CDOView) + { + CDOView view = (CDOView)element; + if (produceObjectStateChangedEvents()) + { + view.removeObjectHandler(objectHandler); + } + + if (view instanceof CDOTransaction) + { + CDOTransaction transaction = (CDOTransaction)view; + if (produceObjectModificationEvents()) + { + transaction.removeTransactionHandler(transactionHandler1); + } + + if (produceTransactionDemarcationEvents()) + { + transaction.removeTransactionHandler(transactionHandler2); + } + } + } + } + + protected boolean produceObjectStateChangedEvents() + { + return true; + } + + protected boolean produceObjectModificationEvents() + { + return true; + } + + protected boolean produceTransactionDemarcationEvents() + { + return true; + } + + /** + * @author Eike Stepper + */ + public static final class CDOObjectStateChangedEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private final CDOObject object; + + private final CDOState oldState; + + private final CDOState newState; + + private CDOObjectStateChangedEvent(CDOView view, CDOObject object, CDOState oldState, CDOState newState) + { + super(view); + this.object = object; + this.oldState = oldState; + this.newState = newState; + } + + @Override + public CDOView getSource() + { + return (CDOView)super.getSource(); + } + + public CDOObject getObject() + { + return object; + } + + public CDOState getOldState() + { + return oldState; + } + + public CDOState getNewState() + { + return newState; + } + + @Override + protected String formatAdditionalParameters() + { + return "object=" + object + ", oldState=" + oldState + ", newState=" + newState; + } + } + + /** + * @author Eike Stepper + */ + public static final class CDOAttachingObjectEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private final CDOObject object; + + private CDOAttachingObjectEvent(CDOTransaction transaction, CDOObject object) + { + super(transaction); + this.object = object; + } + + @Override + public CDOTransaction getSource() + { + return (CDOTransaction)super.getSource(); + } + + public CDOObject getObject() + { + return object; + } + + @Override + protected String formatAdditionalParameters() + { + return "object=" + object; + } + } + + /** + * @author Eike Stepper + */ + public static final class CDODetachingObjectEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private final CDOObject object; + + private CDODetachingObjectEvent(CDOTransaction transaction, CDOObject object) + { + super(transaction); + this.object = object; + } + + @Override + public CDOTransaction getSource() + { + return (CDOTransaction)super.getSource(); + } + + public CDOObject getObject() + { + return object; + } + + @Override + protected String formatAdditionalParameters() + { + return "object=" + object; + } + } + + /** + * @author Eike Stepper + */ + public static final class CDOModifyingObjectEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private final CDOObject object; + + private final CDOFeatureDelta featureDelta; + + private CDOModifyingObjectEvent(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureDelta) + { + super(transaction); + this.object = object; + this.featureDelta = featureDelta; + } + + @Override + public CDOTransaction getSource() + { + return (CDOTransaction)super.getSource(); + } + + public CDOObject getObject() + { + return object; + } + + public CDOFeatureDelta getFeatureDelta() + { + return featureDelta; + } + + @Override + protected String formatAdditionalParameters() + { + return "object=" + object + ", featureDelta=" + featureDelta; + } + } + + /** + * @author Eike Stepper + */ + public static final class CDOCommittingTransactionEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private final CDOCommitContext commitContext; + + private CDOCommittingTransactionEvent(CDOTransaction transaction, CDOCommitContext commitContext) + { + super(transaction); + this.commitContext = commitContext; + } + + @Override + public CDOTransaction getSource() + { + return (CDOTransaction)super.getSource(); + } + + public CDOCommitContext getCommitContext() + { + return commitContext; + } + + @Override + protected String formatAdditionalParameters() + { + return "commitContext=" + commitContext; + } + } + + /** + * @author Eike Stepper + */ + public static final class CDOCommittedTransactionEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private final CDOCommitContext commitContext; + + private CDOCommittedTransactionEvent(CDOTransaction transaction, CDOCommitContext commitContext) + { + super(transaction); + this.commitContext = commitContext; + } + + @Override + public CDOTransaction getSource() + { + return (CDOTransaction)super.getSource(); + } + + public CDOCommitContext getCommitContext() + { + return commitContext; + } + + @Override + protected String formatAdditionalParameters() + { + return "commitContext=" + commitContext; + } + } + + /** + * @author Eike Stepper + */ + public static final class CDORolledBackTransactionEvent extends Event implements CDOViewEvent + { + private static final long serialVersionUID = 1L; + + private CDORolledBackTransactionEvent(CDOTransaction transaction) + { + super(transaction); + } + + @Override + public CDOTransaction getSource() + { + return (CDOTransaction)super.getSource(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java index 97a32e03c3..625e80f22f 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java @@ -87,6 +87,7 @@ import org.eclipse.net4j.util.collection.ConcurrentArray; import org.eclipse.net4j.util.collection.Pair; import org.eclipse.net4j.util.container.IContainerDelta; import org.eclipse.net4j.util.container.IContainerEvent; +import org.eclipse.net4j.util.container.SelfAttachingContainerListener.DoNotDescend; import org.eclipse.net4j.util.container.SingleDeltaContainerEvent; import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.lifecycle.LifecycleException; @@ -136,7 +137,7 @@ import java.util.Set; * @author Eike Stepper */ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOObject, CDOObjectHistory> - implements InternalCDOView + implements InternalCDOView, DoNotDescend { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_VIEW, AbstractCDOView.class); @@ -440,20 +441,25 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb public synchronized CDOResourceNode[] getElements() { - CDOResource rootResource = getRootResource(); - EList<EObject> contents = rootResource.getContents(); + List<CDOResourceNode> elements = new ArrayList<CDOResourceNode>(); - List<CDOResourceNode> elements = new ArrayList<CDOResourceNode>(contents.size()); - for (EObject object : contents) + if (isActive()) { - if (object instanceof CDOResourceNode) + CDOResource rootResource = getRootResource(); + EList<EObject> contents = rootResource.getContents(); + + for (EObject object : contents) { - CDOResourceNode element = (CDOResourceNode)object; - elements.add(element); + if (object instanceof CDOResourceNode) + { + CDOResourceNode element = (CDOResourceNode)object; + elements.add(element); + } } + + ensureContainerAdapter(rootResource); } - ensureContainerAdapter(rootResource); return elements.toArray(new CDOResourceNode[elements.size()]); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java index fabb91e0b4..c7363cf9b1 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java @@ -2017,7 +2017,7 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv @Override public String toString() { - return "CDOViewInvalidationEvent: " + revisionDeltas; //$NON-NLS-1$ + return "CDOViewInvalidationEvent" + revisionDeltas; //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/CheckUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/CheckUtil.java index b8c1d1c9c7..8acb06a4d2 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/CheckUtil.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/CheckUtil.java @@ -10,6 +10,8 @@ */ package org.eclipse.net4j.util; +import org.eclipse.net4j.util.io.IOUtil; + /** * Provides static methods that check object states and invocation arguments. * @@ -18,6 +20,8 @@ package org.eclipse.net4j.util; */ public final class CheckUtil { + private static int counter; + private CheckUtil() { } @@ -61,4 +65,20 @@ public final class CheckUtil throw new IllegalStateException(handleName + " is null"); //$NON-NLS-1$ } } + + /** + * @since 3.6 + */ + public static void countUp(String message) + { + IOUtil.OUT().println(message + (++counter)); + } + + /** + * @since 3.6 + */ + public static void countDown(String message) + { + IOUtil.OUT().println(message + --counter); + } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/SelfAttachingContainerListener.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/SelfAttachingContainerListener.java new file mode 100644 index 0000000000..ea544fa576 --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/SelfAttachingContainerListener.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2004-2015 Eike Stepper (Berlin, Germany) 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.net4j.util.container; + +import org.eclipse.net4j.util.container.IContainerDelta.Kind; +import org.eclipse.net4j.util.event.EventUtil; +import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.IListener; +import org.eclipse.net4j.util.lifecycle.ILifecycle; +import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; + +/** + * @author Eike Stepper + * @since 3.6 + */ +public class SelfAttachingContainerListener implements IListener +{ + public SelfAttachingContainerListener() + { + } + + public void attach(Object element) + { + if (shouldAttach(element)) + { + EventUtil.addListener(element, this); + + if (shouldDescend(element)) + { + try + { + Object[] children = ContainerUtil.getElements(element); + if (children != null) + { + for (Object child : children) + { + try + { + attach(child); + } + catch (Exception ex) + { + handleException(ex); + } + } + } + } + catch (Exception ex) + { + handleException(ex); + } + } + } + } + + public void detach(Object element) + { + if (shouldAttach(element)) + { + if (shouldDescend(element)) + { + try + { + Object[] children = ContainerUtil.getElements(element); + if (children != null) + { + for (Object child : children) + { + try + { + detach(child); + } + catch (Exception ex) + { + handleException(ex); + } + } + } + } + catch (Exception ex) + { + handleException(ex); + } + } + + EventUtil.removeListener(element, this); + } + } + + public void notifyEvent(IEvent event) + { + if (event instanceof IContainerEvent<?>) + { + notifyContainerEvent((IContainerEvent<?>)event); + } + else + { + notifyOtherEvent(event); + } + } + + protected void notifyContainerEvent(IContainerEvent<?> event) + { + for (IContainerDelta<?> delta : event.getDeltas()) + { + final Object element = delta.getElement(); + + if (delta.getKind() == Kind.ADDED) + { + if (isWaitForActive() && !isActive(element)) + { + EventUtil.addListener(element, new LifecycleEventAdapter() + { + @Override + protected void onActivated(ILifecycle lifecycle) + { + lifecycle.removeListener(this); + attach(element); + } + }); + } + else + { + attach(element); + } + } + else + { + detach(element); + } + } + } + + protected void notifyOtherEvent(IEvent event) + { + } + + protected boolean shouldAttach(Object element) + { + return true; + } + + protected boolean shouldDescend(Object element) + { + return !(element instanceof DoNotDescend); + } + + protected boolean isWaitForActive() + { + return true; + } + + protected boolean isActive(Object element) + { + return LifecycleUtil.isActive(element); + } + + protected void handleException(Exception ex) + { + } + + /** + * @author Eike Stepper + */ + public interface DoNotDescend + { + } + + /** + * @author Eike Stepper + */ + public static class Delegating extends SelfAttachingContainerListener + { + private final IListener delegate; + + private final boolean delegateContainerEvents; + + public Delegating(IListener delegate, boolean delegateContainerEvents) + { + this.delegate = delegate; + this.delegateContainerEvents = delegateContainerEvents; + } + + public Delegating(IListener delegate) + { + this(delegate, false); + } + + @Override + protected void notifyContainerEvent(IContainerEvent<?> event) + { + super.notifyContainerEvent(event); + + if (delegateContainerEvents) + { + delegate.notifyEvent(event); + } + } + + @Override + protected void notifyOtherEvent(IEvent event) + { + delegate.notifyEvent(event); + } + } +} diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/EventPrinter.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/EventPrinter.java new file mode 100644 index 0000000000..9ed88a166c --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/EventPrinter.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Eike Stepper (Berlin, Germany) 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.net4j.util.event; + +import org.eclipse.net4j.util.io.IOUtil; + +import java.io.PrintStream; + +/** + * @author Eike Stepper + * @since 3.6 + */ +public class EventPrinter implements IListener +{ + private final PrintStream stream; + + public EventPrinter(PrintStream stream) + { + this.stream = stream; + } + + public EventPrinter() + { + this(IOUtil.OUT()); + } + + public void notifyEvent(IEvent event) + { + stream.println(event); + } +} |