Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 118854 Details for
Bug 245446
Non-inherited transaction options prevent transaction reuse
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
A transaction option metadata implementation
option-metadata.patch (text/plain), 37.30 KB, created by
Christian Damus
on 2008-11-26 20:48:00 EST
(
hide
)
Description:
A transaction option metadata implementation
Filename:
MIME Type:
Creator:
Christian Damus
Created:
2008-11-26 20:48:00 EST
Size:
37.30 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.emf.workspace.tests >Index: src/org/eclipse/emf/workspace/tests/AbstractEMFOperationTest.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/tests/org.eclipse.emf.workspace.tests/src/org/eclipse/emf/workspace/tests/AbstractEMFOperationTest.java,v >retrieving revision 1.12 >diff -u -r1.12 AbstractEMFOperationTest.java >--- src/org/eclipse/emf/workspace/tests/AbstractEMFOperationTest.java 13 Nov 2008 01:16:38 -0000 1.12 >+++ src/org/eclipse/emf/workspace/tests/AbstractEMFOperationTest.java 27 Nov 2008 01:29:31 -0000 >@@ -9,8 +9,8 @@ > * > * Contributors: > * IBM - Initial API and implementation >- * Zeligsoft - Bugs 218276, 245419, 245393, 250253 >- * IBM - Bug 245393 >+ * Zeligsoft - Bugs 218276, 245419, 245393, 250253, 247691 (restore method accessibility) >+ * IBM - Bugs 245393, 247691 > * > * </copyright> > * >@@ -18,6 +18,8 @@ > */ > package org.eclipse.emf.workspace.tests; > >+import java.lang.reflect.Method; >+import java.util.Collections; > import java.util.Map; > > import junit.framework.Test; >@@ -962,6 +964,65 @@ > l.uninstall(domain); > } > } >+ >+ /** >+ * Tests that child operations reuse their parent's transaction when the parent >+ * has the {@link Transaction#OPTION_VALIDATE_EDIT} option, but the child does not. >+ */ >+ public void test_inheritValidateEditOption_247691() { >+ >+ final CompositeEMFOperation outer = new CompositeEMFOperation(domain, >+ "outer", //$NON-NLS-1$ >+ Collections.singletonMap(Transaction.OPTION_VALIDATE_EDIT, >+ Boolean.TRUE)); >+ >+ outer.setTransactionNestingEnabled(false); >+ >+ AbstractEMFOperation inner = new AbstractEMFOperation(domain, "inner") { //$NON-NLS-1$ >+ >+ @Override >+ public boolean canExecute() { >+ return true; >+ } >+ >+ @Override >+ protected IStatus doExecute(IProgressMonitor monitor, >+ IAdaptable info) >+ throws ExecutionException { >+ >+ Method getTransactionMethod = null; >+ >+ try { >+ getTransactionMethod = AbstractEMFOperation.class >+ .getDeclaredMethod("getTransaction", new Class[0]); //$NON-NLS-1$ >+ getTransactionMethod.setAccessible(true); >+ Object outerTransaction = getTransactionMethod.invoke( >+ outer, new Object[0]); >+ Object innerTransaction = getTransactionMethod.invoke(this, >+ new Object[0]); >+ assertTrue("Should have reused the parent transaction", //$NON-NLS-1$ >+ innerTransaction == null >+ || innerTransaction == outerTransaction); >+ return Status.OK_STATUS; >+ >+ } catch (Exception e) { >+ throw new ExecutionException(e.getMessage(), e); >+ } finally { >+ if (getTransactionMethod != null) { >+ getTransactionMethod.setAccessible(false); >+ } >+ } >+ } >+ }; >+ >+ outer.add(inner); >+ >+ try { >+ outer.execute(new NullProgressMonitor(), null); >+ } catch (ExecutionException e) { >+ fail("Unexpected exception: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ } > > // > // Fixtures >#P org.eclipse.emf.transaction >Index: src/org/eclipse/emf/transaction/util/TransactionUtil.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/plugins/org.eclipse.emf.transaction/src/org/eclipse/emf/transaction/util/TransactionUtil.java,v >retrieving revision 1.7 >diff -u -r1.7 TransactionUtil.java >--- src/org/eclipse/emf/transaction/util/TransactionUtil.java 14 Nov 2007 18:14:00 -0000 1.7 >+++ src/org/eclipse/emf/transaction/util/TransactionUtil.java 27 Nov 2008 01:29:54 -0000 >@@ -1,7 +1,7 @@ > /** > * <copyright> > * >- * Copyright (c) 2006, 2007 IBM Corporation and others. >+ * Copyright (c) 2006, 2008 IBM Corporation, Zeligsoft Inc., 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 >@@ -9,6 +9,7 @@ > * > * Contributors: > * IBM - Initial API and implementation >+ * Zeligsoft - Bug 245446 > * > * </copyright> > * >@@ -352,4 +353,29 @@ > > return (RunnableWithResult<T>) domain.createPrivilegedRunnable(runnable); > } >+ >+ /** >+ * Gets the best transaction-option registry available for the specified >+ * editing <tt>domain</tt>. Usually, it will be a registry that is local to >+ * that domain, but it may be the >+ * {@linkplain Transaction.OptionMetadata.Registry#INSTANCE shared instance} >+ * under extreme circumstances. >+ * >+ * @param domain >+ * an editing domain >+ * @return its transaction options registry, never <code>null</code> >+ * >+ * @since 1.3 >+ */ >+ public static Transaction.OptionMetadata.Registry getTransactionOptionRegistry( >+ TransactionalEditingDomain domain) { >+ Transaction.OptionMetadata.Registry result = getAdapter(domain, >+ Transaction.OptionMetadata.Registry.class); >+ >+ if (result == null) { >+ result = Transaction.OptionMetadata.Registry.INSTANCE; >+ } >+ >+ return result; >+ } > } >Index: src/org/eclipse/emf/transaction/impl/TransactionImpl.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/plugins/org.eclipse.emf.transaction/src/org/eclipse/emf/transaction/impl/TransactionImpl.java,v >retrieving revision 1.21 >diff -u -r1.21 TransactionImpl.java >--- src/org/eclipse/emf/transaction/impl/TransactionImpl.java 13 Nov 2008 01:16:55 -0000 1.21 >+++ src/org/eclipse/emf/transaction/impl/TransactionImpl.java 27 Nov 2008 01:29:47 -0000 >@@ -9,7 +9,7 @@ > * > * Contributors: > * IBM - Initial API and implementation >- * Zeligsoft - Bugs 145877, 250253 >+ * Zeligsoft - Bugs 145877, 250253, 245446 > * > * </copyright> > * >@@ -832,26 +832,20 @@ > private void inheritOptions(Transaction parent) { > > // if we have no parent transaction, then we are a root and we "inherit" >- // the editing domain's default transaction options >- Map<?, ?> parentOptions = (parent == null) ? >+ // the editing domain's default transaction options. In the root case, >+ // we don't consider whether an option is hereditary because, of course, >+ // we aren't actually inheriting it from any other transaction >+ final boolean isRoot = parent == null; >+ Map<?, ?> parentOptions = isRoot ? > getDefaultOptions(getEditingDomain()) : parent.getOptions(); > > if (parentOptions != null) { >- for (Map.Entry<?, ?> next : parentOptions.entrySet()) { >- Object option = next.getKey(); >- >- if (ALLOW_CHANGE_PROPAGATION_BLOCKING.equals(option)) { >- // Do not inherit the allow block option if we have the >- // block option applied >- if (!mutableOptions.containsKey(BLOCK_CHANGE_PROPAGATION)) { >- mutableOptions.put(option, next.getValue()); >- } >- } else if (BLOCK_CHANGE_PROPAGATION.equals(option)) { >- // don't inherit the block option! >- } else if (!mutableOptions.containsKey(option)) { >- // overridden by child transaction options >- mutableOptions.put(option, next.getValue()); >- } >+ Transaction.OptionMetadata.Registry reg = TransactionUtil >+ .getTransactionOptionRegistry(getEditingDomain()); >+ >+ for (Object option : parentOptions.keySet()) { >+ reg.getOptionMetadata(option).inherit(parentOptions, >+ mutableOptions, isRoot); > } > } > } >Index: src/org/eclipse/emf/transaction/impl/TransactionalEditingDomainImpl.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/plugins/org.eclipse.emf.transaction/src/org/eclipse/emf/transaction/impl/TransactionalEditingDomainImpl.java,v >retrieving revision 1.19 >diff -u -r1.19 TransactionalEditingDomainImpl.java >--- src/org/eclipse/emf/transaction/impl/TransactionalEditingDomainImpl.java 20 Sep 2008 21:23:08 -0000 1.19 >+++ src/org/eclipse/emf/transaction/impl/TransactionalEditingDomainImpl.java 27 Nov 2008 01:29:53 -0000 >@@ -9,7 +9,7 @@ > * > * Contributors: > * IBM - Initial API and implementation >- * Zeligsoft - Bugs 177642, 145877 >+ * Zeligsoft - Bugs 177642, 145877, 245446 > * > * </copyright> > * >@@ -56,6 +56,7 @@ > import org.eclipse.emf.transaction.internal.Tracing; > import org.eclipse.emf.transaction.internal.l10n.Messages; > import org.eclipse.emf.transaction.util.Adaptable; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadataRegistry; > import org.eclipse.emf.transaction.util.Lock; > import org.eclipse.emf.transaction.util.TransactionUtil; > >@@ -68,6 +69,7 @@ > * <ul> > * <li>{@link TransactionalEditingDomain.DefaultOptions}</li> > * <li>{@link TransactionalEditingDomain.Lifecycle} (since 1.3)</li> >+ * <li>{@link Transaction.Option.Registry} (since 1.3)</li> > * </ul> > * > * @author Christian W. Damus (cdamus) >@@ -112,6 +114,7 @@ > TransactionImpl.DEFAULT_UNDO_REDO_OPTIONS); > > private LifecycleImpl lifecycle; >+ private Transaction.OptionMetadata.Registry optionMetadata; > > /** > * Initializes me with my adapter factory, command stack, and resource set. >@@ -931,7 +934,9 @@ > public <T> T getAdapter(Class<? extends T> adapterType) { > T result; > >- if (adapterType == DefaultOptions.class) { >+ if (adapterType == Transaction.OptionMetadata.Registry.class) { >+ result = (T) getOptionMetadata(); >+ } else if (adapterType == DefaultOptions.class) { > result = (T) this; > } else if (adapterType == Lifecycle.class) { > result = (T) getLifecycle(); >@@ -1014,6 +1019,34 @@ > return new LifecycleImpl(); > } > >+ /** >+ * Obtains my lazily-created transaction option metadata registry. >+ * >+ * @return my option metadata registry >+ * >+ * @since 1.3 >+ */ >+ protected synchronized final Transaction.OptionMetadata.Registry getOptionMetadata() { >+ if (optionMetadata == null) { >+ optionMetadata = createOptionMetadataRegistry(); >+ } >+ >+ return optionMetadata; >+ } >+ >+ /** >+ * Creates a new transaction option metadata registry. >+ * Subclasses may override to create their own implementation, although it >+ * would hardly seem interesting to do so. >+ * >+ * @return a new option metadata registry >+ * >+ * @since 1.3 >+ */ >+ protected Transaction.OptionMetadata.Registry createOptionMetadataRegistry() { >+ return new BasicTransactionOptionMetadataRegistry(); >+ } >+ > // > // Nested classes > // >Index: src/org/eclipse/emf/transaction/Transaction.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/plugins/org.eclipse.emf.transaction/src/org/eclipse/emf/transaction/Transaction.java,v >retrieving revision 1.7 >diff -u -r1.7 Transaction.java >--- src/org/eclipse/emf/transaction/Transaction.java 14 Nov 2007 18:14:01 -0000 1.7 >+++ src/org/eclipse/emf/transaction/Transaction.java 27 Nov 2008 01:29:46 -0000 >@@ -1,7 +1,7 @@ > /** > * <copyright> > * >- * Copyright (c) 2005, 2007 IBM Corporation and others. >+ * Copyright (c) 2005, 2008 IBM Corporation, Zeligsoft Inc., 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 >@@ -9,6 +9,7 @@ > * > * Contributors: > * IBM - Initial API and implementation >+ * Zeligsoft - Bug 245446 > * > * </copyright> > * >@@ -19,6 +20,12 @@ > import java.util.Map; > > import org.eclipse.core.runtime.IStatus; >+import org.eclipse.emf.transaction.impl.TransactionImpl; >+import org.eclipse.emf.transaction.internal.AllowChangePropagationBlockingOption; >+import org.eclipse.emf.transaction.internal.BlockChangePropagationOption; >+import org.eclipse.emf.transaction.internal.ValidateEditOption; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadata; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadataRegistry; > import org.eclipse.emf.transaction.util.ValidateEditSupport; > > >@@ -187,7 +194,8 @@ > > /** > * Obtains the special options with which I was created. The options >- * (map keys) are defined by the {@link TransactionalEditingDomain} interface. >+ * (map keys) are defined by the {@link #OPTION_NO_NOTIFICATIONS Transaction} >+ * interface. > * > * @return an unmodifiable view of my options > */ >@@ -310,4 +318,218 @@ > * @return my status, most interesting after I have closed > */ > public IStatus getStatus(); >+ >+ // >+ // Nested types >+ // >+ >+ /** >+ * <p> >+ * An optional interface that allows clients to query certain meta-data >+ * about transaction options. >+ * </p> >+ * <p> >+ * This interface is not intended to be implemented by clients. Extend the >+ * {@link BasicTransactionOptionMetadata} class, instead. >+ * </p> >+ * >+ * @noimplement This interface is not intended to be implemented by clients. >+ * >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ * >+ * @see BasicTransactionOptionMetadata >+ */ >+ interface OptionMetadata { >+ >+ /** >+ * Obtains the key of the option that I describe. This is the key that >+ * would be used in the options map of a transaction. >+ * >+ * @return my option >+ */ >+ Object getOption(); >+ >+ /** >+ * <p> >+ * Queries whether the specified option is a tag, meaning that it adorns >+ * a transaction with client-specific information but that it does not >+ * otherwise affect the semantics (or behaviour) of the transaction. >+ * </p> >+ * <p> >+ * Unrecognized options are assumed to be tags, because a transaction >+ * would not be able to interpret their meaning. >+ * </p> >+ * >+ * @return <code>true</code> if the option key is a tag option or if it >+ * is not recognized by this meta-data instance; >+ * <code>false</code> if it is recognized and is known not to be >+ * a tag >+ */ >+ boolean isTag(); >+ >+ /** >+ * <p> >+ * Queries whether the specified option is inherited by nested >+ * transactions. >+ * </p> >+ * <p> >+ * Unrecognized options are assumed to be inherited. >+ * </p> >+ * >+ * @return <code>true</code> if the option is inherited or if it is not >+ * recognized; <code>false</code> if it is not inherited >+ */ >+ boolean isHereditary(); >+ >+ /** >+ * <p> >+ * Obtains the type value of an option. >+ * </p> >+ * <p> >+ * The type of an unrecognized option is assumed to be {@link Object}. >+ * </p> >+ * >+ * @return the default value of the option, or <code>Object</code> if it >+ * is not known >+ */ >+ Class<?> getType(); >+ >+ /** >+ * <p> >+ * Obtains the default value of an option. >+ * </p> >+ * <p> >+ * The default value of an unrecognized option is assumed to be >+ * <code>null</code>. >+ * </p> >+ * >+ * @return the default value of the option, or <code>null</code> if it >+ * is not known >+ */ >+ Object getDefaultValue(); >+ >+ /** >+ * Gets the value (implicit/default or explicit) of my option in the >+ * specified map. >+ * >+ * @param options >+ * an options map >+ * >+ * @return my value in the map >+ */ >+ Object getValue(Map<?, ?> options); >+ >+ /** >+ * Queries whether the specified map has a setting for my option. >+ * >+ * @param options >+ * an options map >+ * @return whether it has a setting for my option >+ */ >+ boolean isSet(Map<?, ?> options); >+ >+ /** >+ * Queries whether the specified options maps have the same value of my >+ * option, whether that be implicit or explicit. That is, this method >+ * accounts for default values and such complex cases as the >+ * {@link Transaction#OPTION_VALIDATE_EDIT} in which values of two >+ * different types may mean the same thing. >+ * >+ * @param options1 >+ * an options map >+ * @param options2 >+ * another options map >+ * >+ * @return whether the two maps have the same setting of my option >+ */ >+ boolean sameSetting(Map<?, ?> options1, Map<?, ?> options2); >+ >+ /** >+ * Updates the options map of a child transaction to inherit the setting >+ * in a parent transaction, if it is a hereditary option and the child >+ * does not already have a setting for it. >+ * >+ * @param parentOptions >+ * the options map to inherit a value from. It is conceivable >+ * that inheritance of an option may depend on more than one >+ * option in this parent map >+ * @param childOptions >+ * the map that is to inherit the option setting >+ * @param force >+ * whether to inherit the option anyway despite that it is >+ * not hereditary. This is used for application of default >+ * options, and can be ignored by the implementor if >+ * necessary. Also, clients must not use this parameter to >+ * attempt to override an existing child setting; a >+ * well-behaved option will not do that >+ */ >+ void inherit(Map<?, ?> parentOptions, Map<Object, Object> childOptions, >+ boolean force); >+ >+ /** >+ * <p> >+ * A registry of metadata describing transaction options. The default >+ * implementation of the {@link TransactionalEditingDomain} interface >+ * provides a transaction option registry as an adapter. >+ * </p> >+ * <p> >+ * This interface is not intended to be implemented by clients. >+ * </p> >+ * >+ * @noimplement This interface is not intended to be implemented by >+ * clients. >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ */ >+ interface Registry { >+ >+ /** >+ * The shared transaction option metadata registry. >+ */ >+ Registry INSTANCE = new BasicTransactionOptionMetadataRegistry(null) { >+ >+ private static final long serialVersionUID = 1L; >+ >+ { >+ // the options that we know >+ register(BasicTransactionOptionMetadata.newBoolean( >+ Transaction.OPTION_NO_NOTIFICATIONS, false)); >+ register(BasicTransactionOptionMetadata.newBoolean( >+ Transaction.OPTION_NO_TRIGGERS, false)); >+ register(BasicTransactionOptionMetadata.newBoolean( >+ Transaction.OPTION_NO_VALIDATION, false)); >+ register(BasicTransactionOptionMetadata.newBoolean( >+ Transaction.OPTION_NO_UNDO, false)); >+ register(BasicTransactionOptionMetadata.newBoolean( >+ Transaction.OPTION_UNPROTECTED, false)); >+ register(BasicTransactionOptionMetadata.newBoolean( >+ Transaction.OPTION_IS_UNDO_REDO_TRANSACTION, false)); >+ >+ register(new ValidateEditOption()); >+ register(new BasicTransactionOptionMetadata( >+ Transaction.OPTION_VALIDATE_EDIT_CONTEXT)); >+ >+ register(BasicTransactionOptionMetadata.newBoolean( >+ TransactionImpl.OPTION_IS_TRIGGER_TRANSACTION, false)); >+ register(new AllowChangePropagationBlockingOption()); >+ register(new BlockChangePropagationOption()); >+ } >+ }; >+ >+ /** >+ * Obtains a metadata object describing the specified transaction >+ * option. For unrecognized options, a default meta-data is provided >+ * that gives reasonable answers. >+ * >+ * @param option >+ * an option key >+ * @return the option meta-data (never <code>null</code>) >+ */ >+ Transaction.OptionMetadata getOptionMetadata(Object option); >+ } >+ >+ } > } >Index: src/org/eclipse/emf/transaction/internal/AllowChangePropagationBlockingOption.java >=================================================================== >RCS file: src/org/eclipse/emf/transaction/internal/AllowChangePropagationBlockingOption.java >diff -N src/org/eclipse/emf/transaction/internal/AllowChangePropagationBlockingOption.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/transaction/internal/AllowChangePropagationBlockingOption.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,56 @@ >+/** >+ * <copyright> >+ * >+ * Copyright (c) 2008 Zeligsoft Inc. 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: >+ * Zeligsoft - Initial API and implementation >+ * >+ * </copyright> >+ * >+ * $Id$ >+ */ >+ >+package org.eclipse.emf.transaction.internal; >+ >+import java.util.Map; >+ >+import org.eclipse.emf.transaction.impl.TransactionImpl; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadata; >+ >+ >+/** >+ * Metadata implementation for the non-trivial complexity of the >+ * {@link TransactionImpl#ALLOW_CHANGE_PROPAGATION_BLOCKING} transaction option. >+ * >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ */ >+public class AllowChangePropagationBlockingOption >+ extends BasicTransactionOptionMetadata { >+ >+ /** >+ * Initializes me. >+ */ >+ public AllowChangePropagationBlockingOption() { >+ super(TransactionImpl.ALLOW_CHANGE_PROPAGATION_BLOCKING, false, true, >+ Boolean.class, Boolean.FALSE); >+ } >+ >+ @Override >+ public void inherit(Map<?, ?> parentOptions, >+ Map<Object, Object> childOptions, boolean force) { >+ >+ // do not inherit the allow block option if the block option is >+ // already applied >+ if (!childOptions.containsKey(TransactionImpl.BLOCK_CHANGE_PROPAGATION)) { >+ childOptions.put(getOption(), getValue(parentOptions)); >+ } >+ } >+ >+} >Index: src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadata.java >=================================================================== >RCS file: src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadata.java >diff -N src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadata.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadata.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,157 @@ >+/** >+ * <copyright> >+ * >+ * Copyright (c) 2008 Zeligsoft Inc. 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: >+ * Zeligsoft - Initial API and implementation >+ * >+ * </copyright> >+ * >+ * $Id$ >+ */ >+ >+package org.eclipse.emf.transaction.util; >+ >+import java.util.Map; >+ >+import org.eclipse.emf.transaction.Transaction; >+ >+/** >+ * A simple implementation of the {@link Transaction.OptionMetadata} interface. >+ * >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ */ >+public class BasicTransactionOptionMetadata >+ implements Transaction.OptionMetadata { >+ >+ private final Object option; >+ >+ private boolean isTag; >+ >+ private boolean isHereditary; >+ >+ private Class<?> type; >+ >+ private Object defaultValue; >+ >+ /** >+ * Initializes me with my option key. >+ * >+ * @param option >+ * my option key >+ */ >+ public BasicTransactionOptionMetadata(Object option) { >+ this(option, true, true, Object.class, null); >+ } >+ >+ /** >+ * Initializes me with my option key and other details. >+ * >+ * @param option >+ * my option key >+ * @param isTag >+ * whether the option is a tag >+ * @param isHereditary >+ * whether the option is inherited >+ * @param type >+ * the option type >+ * @param defaultValue >+ * the option's defaul value >+ */ >+ public BasicTransactionOptionMetadata(Object option, boolean isTag, >+ boolean isHereditary, Class<?> type, Object defaultValue) { >+ this.option = option; >+ this.isTag = isTag; >+ this.isHereditary = isHereditary; >+ this.type = type; >+ this.defaultValue = defaultValue; >+ } >+ >+ public Object getDefaultValue() { >+ return defaultValue; >+ } >+ >+ public final Object getOption() { >+ return option; >+ } >+ >+ public Class<?> getType() { >+ return type; >+ } >+ >+ public boolean isHereditary() { >+ return isHereditary; >+ } >+ >+ public boolean isTag() { >+ return isTag; >+ } >+ >+ public Object getValue(Map<?, ?> options) { >+ return options.containsKey(option) >+ ? options.get(option) >+ : getDefaultValue(); >+ } >+ >+ public boolean isSet(Map<?, ?> options) { >+ return options.containsKey(option); >+ } >+ >+ public boolean sameSetting(Map<?, ?> options1, Map<?, ?> options2) { >+ return safeEquals(getValue(options1), getValue(options2)); >+ } >+ >+ public void inherit(Map<?, ?> parentOptions, >+ Map<Object, Object> childOptions, boolean force) { >+ >+ if ((force || isHereditary()) && !isSet(childOptions)) { >+ childOptions.put(option, getValue(parentOptions)); >+ } >+ } >+ >+ protected boolean safeEquals(Object a, Object b) { >+ return (a == null) >+ ? b == null >+ : a.equals(b); >+ } >+ >+ protected Class<?> safeClass(Object o) { >+ return (o == null) >+ ? Void.class >+ : o.getClass(); >+ } >+ >+ /** >+ * Creates a new transaction option meta-data for an heritary, non-tag, >+ * boolean-valued option. >+ * >+ * @param option >+ * the option key >+ * @param defaultValue >+ * the option's default value >+ * >+ * @return the option meta-data >+ */ >+ public static Transaction.OptionMetadata newBoolean(Object option, >+ boolean defaultValue) { >+ >+ return new BasicTransactionOptionMetadata(option, false, true, >+ Boolean.class, Boolean.valueOf(defaultValue)); >+ } >+ >+ @Override >+ public String toString() { >+ return "Option[key=" + getOption() //$NON-NLS-1$ >+ + ", isTag=" + isTag() //$NON-NLS-1$ >+ + ", isHereditary=" + isHereditary() //$NON-NLS-1$ >+ + ", type=" + getType().getName() //$NON-NLS-1$ >+ + ", default=" + getDefaultValue() + ']'; //$NON-NLS-1$ >+ } >+} >Index: src/org/eclipse/emf/transaction/internal/BlockChangePropagationOption.java >=================================================================== >RCS file: src/org/eclipse/emf/transaction/internal/BlockChangePropagationOption.java >diff -N src/org/eclipse/emf/transaction/internal/BlockChangePropagationOption.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/transaction/internal/BlockChangePropagationOption.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,52 @@ >+/** >+ * <copyright> >+ * >+ * Copyright (c) 2008 Zeligsoft Inc. 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: >+ * Zeligsoft - Initial API and implementation >+ * >+ * </copyright> >+ * >+ * $Id$ >+ */ >+ >+package org.eclipse.emf.transaction.internal; >+ >+import java.util.Map; >+ >+import org.eclipse.emf.transaction.impl.TransactionImpl; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadata; >+ >+ >+/** >+ * Metadata implementation for the non-trivial complexity of the >+ * {@link TransactionImpl#BLOCK_CHANGE_PROPAGATION} transaction option. >+ * >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ */ >+public class BlockChangePropagationOption >+ extends BasicTransactionOptionMetadata { >+ >+ /** >+ * Initializes me. >+ */ >+ public BlockChangePropagationOption() { >+ super(TransactionImpl.BLOCK_CHANGE_PROPAGATION, false, false, >+ Boolean.class, Boolean.FALSE); >+ } >+ >+ @Override >+ public void inherit(Map<?, ?> parentOptions, >+ Map<Object, Object> childOptions, boolean force) { >+ >+ // never inherit this option, even when requested to force >+ } >+ >+} >Index: src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadataRegistry.java >=================================================================== >RCS file: src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadataRegistry.java >diff -N src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadataRegistry.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/transaction/util/BasicTransactionOptionMetadataRegistry.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,91 @@ >+/** >+ * <copyright> >+ * >+ * Copyright (c) 2008 Zeligsoft Inc. 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: >+ * Zeligsoft - Initial API and implementation >+ * >+ * </copyright> >+ * >+ * $Id$ >+ */ >+ >+package org.eclipse.emf.transaction.util; >+ >+import org.eclipse.emf.transaction.Transaction; >+ >+/** >+ * A simple implementation of the transaction option metadata registry API. >+ * >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ */ >+public class BasicTransactionOptionMetadataRegistry >+ extends java.util.HashMap<Object, Transaction.OptionMetadata> >+ implements Transaction.OptionMetadata.Registry { >+ >+ private static final long serialVersionUID = 1L; >+ >+ private final Transaction.OptionMetadata.Registry delegate; >+ >+ /** >+ * Initializes me with the shared registry instance as my delegate. >+ */ >+ public BasicTransactionOptionMetadataRegistry() { >+ this(Transaction.OptionMetadata.Registry.INSTANCE); >+ } >+ >+ /** >+ * Initializes me with a registry to which I delegate options that I do not >+ * provide for. >+ * >+ * @param delegate >+ * my delegate >+ */ >+ protected BasicTransactionOptionMetadataRegistry( >+ Transaction.OptionMetadata.Registry delegate) { >+ this.delegate = delegate; >+ } >+ >+ public Transaction.OptionMetadata getOptionMetadata(Object option) { >+ Transaction.OptionMetadata result = get(option); >+ >+ if (result == null) { >+ result = delegatedGetOptionMetadata(option); >+ } >+ >+ if (result == null) { >+ // create an ephemeral default metadata >+ result = new BasicTransactionOptionMetadata(option); >+ } >+ >+ return result; >+ } >+ >+ protected Transaction.OptionMetadata delegatedGetOptionMetadata( >+ Object option) { >+ >+ return (delegate == null) >+ ? null >+ : delegate.getOptionMetadata(option); >+ } >+ >+ /** >+ * Registers an option metadata descriptor. >+ * >+ * @param metadata >+ * the option metadata to register >+ * @return the metadata displaced by the new object, if previously we had a >+ * descriptor for the same option, otherwise <code>null</code> >+ */ >+ public Transaction.OptionMetadata register( >+ Transaction.OptionMetadata metadata) { >+ return put(metadata.getOption(), metadata); >+ } >+} >Index: src/org/eclipse/emf/transaction/internal/ValidateEditOption.java >=================================================================== >RCS file: src/org/eclipse/emf/transaction/internal/ValidateEditOption.java >diff -N src/org/eclipse/emf/transaction/internal/ValidateEditOption.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/transaction/internal/ValidateEditOption.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,72 @@ >+/** >+ * <copyright> >+ * >+ * Copyright (c) 2008 Zeligsoft Inc. 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: >+ * Zeligsoft - Initial API and implementation >+ * >+ * </copyright> >+ * >+ * $Id$ >+ */ >+ >+package org.eclipse.emf.transaction.internal; >+ >+import java.util.Map; >+ >+import org.eclipse.emf.transaction.Transaction; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadata; >+import org.eclipse.emf.transaction.util.ValidateEditSupport; >+ >+/** >+ * Metadata implementation for the non-trivial complexity of the >+ * {@link Transaction#OPTION_VALIDATE_EDIT} transaction option. >+ * >+ * @author Christian W. Damus (cdamus) >+ * >+ * @since 1.3 >+ */ >+public class ValidateEditOption >+ extends BasicTransactionOptionMetadata { >+ >+ /** >+ * Initializes me. >+ */ >+ public ValidateEditOption() { >+ super(Transaction.OPTION_VALIDATE_EDIT, true, false, Object.class, >+ Boolean.FALSE); >+ } >+ >+ @Override >+ public boolean sameSetting(Map<?, ?> options1, Map<?, ?> options2) { >+ >+ Object value1 = getValue(options1); >+ Object value2 = getValue(options2); >+ boolean result = safeEquals(value1, value2); >+ >+ if (!result) { >+ // they may, yet, be equivalent >+ >+ final Class<?> vesd = ValidateEditSupport.Default.class; >+ >+ if (value1 instanceof Boolean) { >+ if ((Boolean) value1) { >+ // TRUE === new >+ // ValidateEditSupport.Default >+ result = safeClass(value2) == vesd; >+ } >+ } else if (safeClass(value1) == vesd) { >+ result = Boolean.TRUE.equals(value2) >+ || (safeClass(value2) == vesd); >+ } >+ } >+ >+ return result; >+ } >+ >+} >#P org.eclipse.emf.workspace >Index: src/org/eclipse/emf/workspace/WorkspaceEditingDomainFactory.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/plugins/org.eclipse.emf.workspace/src/org/eclipse/emf/workspace/WorkspaceEditingDomainFactory.java,v >retrieving revision 1.5 >diff -u -r1.5 WorkspaceEditingDomainFactory.java >--- src/org/eclipse/emf/workspace/WorkspaceEditingDomainFactory.java 2 Nov 2008 18:43:21 -0000 1.5 >+++ src/org/eclipse/emf/workspace/WorkspaceEditingDomainFactory.java 27 Nov 2008 01:30:20 -0000 >@@ -1,7 +1,7 @@ > /** > * <copyright> > * >- * Copyright (c) 2005, 2008 IBM Corporation, Zeligoft Inc., and others. >+ * Copyright (c) 2005, 2008 IBM Corporation, Zeligsoft Inc., 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 >@@ -9,7 +9,7 @@ > * > * Contributors: > * IBM - Initial API and implementation >- * Zeligsoft - Bug 240775 >+ * Zeligsoft - Bugs 240775, 245446 > * > * </copyright> > * >@@ -18,12 +18,17 @@ > package org.eclipse.emf.workspace; > > import org.eclipse.core.commands.operations.IOperationHistory; >+import org.eclipse.core.commands.operations.IUndoableOperation; > import org.eclipse.core.commands.operations.OperationHistoryFactory; > import org.eclipse.emf.ecore.resource.ResourceSet; > import org.eclipse.emf.edit.provider.ComposedAdapterFactory; >+import org.eclipse.emf.transaction.Transaction; > import org.eclipse.emf.transaction.TransactionalEditingDomain; > import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadata; >+import org.eclipse.emf.transaction.util.BasicTransactionOptionMetadataRegistry; > import org.eclipse.emf.workspace.impl.WorkspaceCommandStackImpl; >+import org.eclipse.emf.workspace.internal.EMFWorkspacePlugin; > > /** > * <p> >@@ -47,6 +52,14 @@ > public static final WorkspaceEditingDomainFactory INSTANCE = > new WorkspaceEditingDomainFactory(); > >+ static { >+ BasicTransactionOptionMetadataRegistry reg = (BasicTransactionOptionMetadataRegistry) Transaction.OptionMetadata.Registry.INSTANCE; >+ >+ reg.register(new BasicTransactionOptionMetadata( >+ EMFWorkspacePlugin.OPTION_OWNING_OPERATION, true, true, >+ IUndoableOperation.class, null)); >+ } >+ > /** > * Initializes me. > */ >@@ -88,7 +101,7 @@ > * > * @return the new editing domain > */ >- public TransactionalEditingDomain createEditingDomain(IOperationHistory history) { >+ public synchronized TransactionalEditingDomain createEditingDomain(IOperationHistory history) { > WorkspaceCommandStackImpl stack = new WorkspaceCommandStackImpl(history); > stack.setResourceUndoContextPolicy(getResourceUndoContextPolicy()); > >@@ -111,7 +124,7 @@ > * > * @return the new editing domain > */ >- public TransactionalEditingDomain createEditingDomain(ResourceSet rset, IOperationHistory history) { >+ public synchronized TransactionalEditingDomain createEditingDomain(ResourceSet rset, IOperationHistory history) { > WorkspaceCommandStackImpl stack = new WorkspaceCommandStackImpl(history); > stack.setResourceUndoContextPolicy(getResourceUndoContextPolicy()); > >Index: src/org/eclipse/emf/workspace/AbstractEMFOperation.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.transaction/plugins/org.eclipse.emf.workspace/src/org/eclipse/emf/workspace/AbstractEMFOperation.java,v >retrieving revision 1.21 >diff -u -r1.21 AbstractEMFOperation.java >--- src/org/eclipse/emf/workspace/AbstractEMFOperation.java 13 Nov 2008 01:17:04 -0000 1.21 >+++ src/org/eclipse/emf/workspace/AbstractEMFOperation.java 27 Nov 2008 01:30:20 -0000 >@@ -203,13 +203,38 @@ > */ > private boolean optionsDiffer(Map<?, ?> options) { > boolean result = true; >- >- Transaction active = >- ((InternalTransactionalEditingDomain) getEditingDomain()).getActiveTransaction(); >+ >+ Transaction active = ((InternalTransactionalEditingDomain) getEditingDomain()) >+ .getActiveTransaction(); > if ((active != null) && !active.isReadOnly()) { >- result = !active.getOptions().equals(options); >+ Transaction.OptionMetadata.Registry reg = TransactionUtil >+ .getTransactionOptionRegistry(getEditingDomain()); >+ >+ result = false; // let's look for a difference >+ Map<?, ?> activeOptions = active.getOptions(); >+ >+ // iterate the options passed in that would be applied to the >+ // nested transaction, because if the active (to-be parent) >+ // specifies more options, then they would be inherited, anyway >+ for (Map.Entry<?, ?> next : options.entrySet()) { >+ Object option = next.getKey(); >+ >+ Transaction.OptionMetadata metadata = reg >+ .getOptionMetadata(option); >+ >+ // tags don't force child transactions. Clients would have >+ // to disable nesting if it really matters to them, or else >+ // override the option meta-data in their editing domain's >+ // local registry >+ if (!metadata.isTag() >+ && !metadata.sameSetting(options, activeOptions)) { >+ >+ result = true; >+ break; >+ } >+ } > } >- >+ > return result; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
give.a.damus
:
review?
Actions:
View
|
Diff
Attachments on
bug 245446
: 118854