diff options
7 files changed, 419 insertions, 89 deletions
diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/PersistenceOptions.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/PersistenceOptions.java index 388d81a49..6d3a370ce 100644 --- a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/PersistenceOptions.java +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/PersistenceOptions.java @@ -12,7 +12,7 @@ * * </copyright> * - * $Id: PersistenceOptions.java,v 1.15 2006/11/12 23:59:17 mtaal Exp $ + * $Id: PersistenceOptions.java,v 1.16 2006/11/28 06:13:36 mtaal Exp $ */ package org.eclipse.emf.teneo; @@ -29,6 +29,8 @@ import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.eclipse.emf.teneo.ecore.EClassNameStrategy; +import org.eclipse.emf.teneo.ecore.EClassNameStrategyUtils; import org.eclipse.emf.teneo.util.SQLCaseStrategy; import org.eclipse.emf.teneo.util.SQLCaseStrategyImpl; @@ -38,7 +40,7 @@ import org.eclipse.emf.teneo.util.SQLCaseStrategyImpl; * As a convenience, this class offers type-safe property accessor wrappers. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> - * @version $Revision: 1.15 $ + * @version $Revision: 1.16 $ */ public class PersistenceOptions { @@ -315,8 +317,9 @@ public class PersistenceOptions { } /** Returns the qualify entity names option, returns QUALIFY_ENTITY_NAME_NO ("no") */ - public String getQualifyEntityName() { - return properties.getProperty(QUALIFY_ENTITY_NAME, QUALIFY_ENTITY_NAME_NO); + public EClassNameStrategy getEClassNameStrategy() { + // note create uses singletons + return EClassNameStrategyUtils.create(properties.getProperty(QUALIFY_ENTITY_NAME, QUALIFY_ENTITY_NAME_NO)); } /** Returns the default second level caching strategy, default value is NONE (no second level caching). */ diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/DefaultEClassNameStrategy.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/DefaultEClassNameStrategy.java new file mode 100644 index 000000000..b92747416 --- /dev/null +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/DefaultEClassNameStrategy.java @@ -0,0 +1,72 @@ +package org.eclipse.emf.teneo.ecore;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+
+/**
+ * This implementation assumes that EClass names are unique. It will (de)Resolve using
+ * the EClass name.
+ * <p>
+ * TODO: Should be moved to Teneo project.
+ *
+ * @author <a href="lmfridael@elver.org">Laurens Fridael</a>
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class DefaultEClassNameStrategy implements EClassNameStrategy {
+
+ /** The singleton instance as it is thread safe */
+ public static final DefaultEClassNameStrategy INSTANCE = new DefaultEClassNameStrategy();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.elver.ecore.spring.EClassResolver#deResolve(org.eclipse.emf.ecore.EClass)
+ */
+ public String toUniqueName(EClass eClass) {
+ if (eClass == EOBJECT_ECLASS) {
+ return EOBJECT_ECLASS_URI;
+ }
+
+ if (eClass == null) {
+ throw new IllegalArgumentException("EClass cannot be null.");
+ }
+ return eClass.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.elver.ecore.spring.EClassResolver#resolve(java.lang.String)
+ */
+ public EClass toEClass(String eClassName, EPackage[] epackages) {
+ if (eClassName == null) {
+ throw new IllegalArgumentException("eClassName may not be null");
+ }
+
+ if (eClassName.compareTo(EOBJECT_ECLASS_URI) == 0) {
+ return EcorePackage.eINSTANCE.getEObject();
+ }
+
+ // now try all epackages
+ EClass eClass = null;
+ for (int i = 0; i < epackages.length; i++) {
+ final EPackage ePackage = epackages[i];
+ final EClassifier eClassifier = ePackage.getEClassifier(eClassName);
+ if (eClassifier instanceof EClass) {
+ if (eClass != null) {
+ // doubly entry! Actually require different resolver
+ throw new IllegalArgumentException("There is more than one EClass with the same name (" + eClassName +
+ " in EPackage " + eClass.getEPackage().getName() + " and " + ePackage.getName() +
+ ". A different EClassResolver should be used.");
+ }
+ eClass = (EClass)eClassifier;
+ }
+ }
+ if (eClass == null) {
+ throw new IllegalArgumentException("No EClass found using " + eClassName);
+ }
+ return eClass;
+ }
+}
diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/EClassNameStrategy.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/EClassNameStrategy.java new file mode 100644 index 000000000..317c93764 --- /dev/null +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/EClassNameStrategy.java @@ -0,0 +1,50 @@ +package org.eclipse.emf.teneo.ecore;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+
+/**
+ * Resolves human usable unique names for EClasses. Internally Elver always uses qualified
+ * String identifiers (EPackage nsuri concatenated with the EClass name). However often
+ * the EClass name is unique and much easier to use for humans.
+ *
+ * @author <a href="lmfridael@elver.org">Laurens Fridael</a>
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public interface EClassNameStrategy {
+
+ /** The EObject eclass */
+ public static EClass EOBJECT_ECLASS = (EClass) EcorePackage.eINSTANCE.getEClassifier("EObject");
+
+ public static String EOBJECT_ECLASS_URI = EcorePackage.eINSTANCE.getNsURI() + "/" + EOBJECT_ECLASS.getName();
+
+ /**
+ * Determines the name for a given EClass. This name can be used in
+ * jsf pages and queries.
+ *
+ * Note if the eClass is the EObject eclass then the string EOBJECT_ECLASS_URI
+ * must be returned.
+ *
+ * @param eClass
+ * The EClass for which to resolve the unique name.
+ * @return The persistence entity name or null if it could not be resolved.
+ * @throws IllegalArgumentException
+ * If eClass is null.
+ */
+ public String toUniqueName(EClass eClass);
+
+ /**
+ * Return the EClass for a certain name.
+ *
+ * Note if the name corresponds to EOBJECT_ECLASS_URI then the
+ * EcorePackage EObject must be returned.
+ *
+ * @return eClass the resolved EClass
+ * @param The EClassName
+ * @throws IllegalArgumentException if the EClass can not be resolved.
+ * @see #deResolve(EClass)
+ */
+ public EClass toEClass(String eClassName, EPackage[] epackages);
+
+}
diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/EClassNameStrategyUtils.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/EClassNameStrategyUtils.java new file mode 100644 index 000000000..a790ae9b8 --- /dev/null +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/EClassNameStrategyUtils.java @@ -0,0 +1,45 @@ +package org.eclipse.emf.teneo.ecore;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.teneo.PersistenceOptions;
+import org.eclipse.emf.teneo.StoreException;
+import org.eclipse.emf.teneo.classloader.ClassLoaderResolver;
+
+/**
+ * Creates the correct EClass name strategy.
+ *
+ * @author <a href="lmfridael@elver.org">Laurens Fridael</a>
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EClassNameStrategyUtils {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EClassNameStrategyUtils.class);
+
+ /**
+ * Creates the correct eclass name strategy based on the String setting.
+ *
+ */
+ public static EClassNameStrategy create(String option) {
+ try {
+ if (option == null) {
+ log.debug("Creating " + DefaultEClassNameStrategy.class.getName() + " as eclass name strategy");
+ return DefaultEClassNameStrategy.INSTANCE;
+ }
+ if (option.compareToIgnoreCase(PersistenceOptions.QUALIFY_ENTITY_NAME_NO) == 0) {
+ log.debug("Creating " + DefaultEClassNameStrategy.class.getName() + " as eclass name strategy");
+ return DefaultEClassNameStrategy.INSTANCE;
+ }
+ if (option.compareToIgnoreCase(PersistenceOptions.QUALIFY_ENTITY_NAME_NSPREFIX) == 0) {
+ log.debug("Creating " + QualifyingEClassNameStrategy.class.getName() + " as case strategy");
+ return QualifyingEClassNameStrategy.INSTANCE;
+ }
+
+ log.debug("Assuming class name creating instance of " + option);
+ return (EClassNameStrategy) ClassLoaderResolver.classForName(option).newInstance();
+ } catch (Exception e) {
+ throw new StoreException("Could not instantiate: " + option, e);
+ }
+ }
+}
\ No newline at end of file diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/QualifyingEClassNameStrategy.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/QualifyingEClassNameStrategy.java new file mode 100644 index 000000000..7b811cb2d --- /dev/null +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/ecore/QualifyingEClassNameStrategy.java @@ -0,0 +1,86 @@ +package org.eclipse.emf.teneo.ecore;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+
+/**
+ * This implementation qualifies the EClassName using the NsPrefix of the EPackage. If
+ * the NsPrefix is not set then the EPackage name is used. The result will be nsPrefix + "." + eclassName.
+ * <p>
+ * TODO: Should be moved to Teneo project.
+ *
+ * @author <a href="lmfridael@elver.org">Laurens Fridael</a>
+ *
+ */
+public class QualifyingEClassNameStrategy implements EClassNameStrategy {
+
+ /** The singleton instance as it is thread safe */
+ public static final QualifyingEClassNameStrategy INSTANCE = new QualifyingEClassNameStrategy();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.elver.ecore.spring.EClassResolver#deResolve(org.eclipse.emf.ecore.EClass)
+ */
+ public String toUniqueName(EClass eClass) {
+ if (eClass == null) {
+ throw new IllegalArgumentException("EClass cannot be null.");
+ }
+ if (eClass == EOBJECT_ECLASS) {
+ return EOBJECT_ECLASS_URI;
+ }
+ String nsPrefix = eClass.getEPackage().getNsPrefix();
+ if (nsPrefix == null) {
+ nsPrefix = eClass.getEPackage().getName();
+ }
+ return nsPrefix + "." + eClass.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.elver.ecore.spring.EClassResolver#resolve(java.lang.String)
+ */
+ public EClass toEClass(String eClassStr, EPackage[] epackages) {
+ if (eClassStr == null) {
+ throw new IllegalArgumentException("eClassStr may not be null");
+ }
+
+ if (eClassStr.compareTo(EOBJECT_ECLASS_URI) == 0) {
+ return EcorePackage.eINSTANCE.getEObject();
+ }
+
+ // get prefix or name
+ final int index = eClassStr.lastIndexOf(".");
+ if (index == -1) {
+ throw new IllegalArgumentException("Illegal eClassStr for this resolver (no dot separating the epackage nsprefix and name): " + eClassStr);
+ }
+ final String nsPrefix = eClassStr.substring(0, index);
+ final String eClassName = eClassStr.substring(index + 1);
+
+ // now try all epackages
+ EClass eClass = null;
+ for (int i = 0; i < epackages.length; i++) {
+ final EPackage ePackage = epackages[i];
+ if (ePackage.getNsPrefix().compareTo(nsPrefix) == 0 ||
+ ePackage.getName().compareTo(nsPrefix) == 0) {
+ final EClassifier eClassifier = ePackage.getEClassifier(eClassName);
+ if (eClassifier instanceof EClass) {
+ if (eClass != null) {
+ // doubly entry! Actually require different resolver
+ throw new IllegalArgumentException("There is more than one EClass with the same identifying String (" + eClassStr +
+ " in EPackage " + eClass.getEPackage().getName() + " and " + ePackage.getName() +
+ ". A different EClassResolver should be used.");
+ }
+ eClass = (EClass)eClassifier;
+ }
+ }
+ }
+ if (eClass == null) {
+ throw new IllegalArgumentException("No EClass found using " + eClassStr);
+ }
+ return eClass;
+ }
+}
\ No newline at end of file diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/resource/StoreResource.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/resource/StoreResource.java index 88cecd895..a73205870 100644 --- a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/resource/StoreResource.java +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/resource/StoreResource.java @@ -12,7 +12,7 @@ * * </copyright> * - * $Id: StoreResource.java,v 1.10 2006/11/25 23:52:18 mtaal Exp $ + * $Id: StoreResource.java,v 1.11 2006/11/28 06:13:36 mtaal Exp $ */ package org.eclipse.emf.teneo.resource; @@ -45,23 +45,32 @@ import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.emf.ecore.xmi.XMLResource; import org.eclipse.emf.teneo.EContainerRepairControl; import org.eclipse.emf.teneo.StoreValidationException; -import org.eclipse.emf.teneo.util.StoreUtil; /** * General part of Store Resources. Main feature is that it keeps track of changes to the resource content and that * settrackingmodification will not load unloaded elists. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> - * @version $Revision: 1.10 $ + * @version $Revision: 1.11 $ */ public abstract class StoreResource extends ResourceImpl { + /** The name of the parameter used for the datastore name */ public static final String DS_NAME_PARAM = "dsname"; /** Prefix to use when specifying query parameters in the uri or in the property file */ public static final String QUERY_PREFIX = "query"; + /** Load strategy */ + public static final String LOAD_STRATEGY_PARAM = "loadStrategy"; + + /** The default strategy */ + public static final String ADD_TO_CONTENTS = "addToContents"; + + /** The just set eResource */ + public static final String SET_ERESOURCE = "setEResource"; + /** The logger */ private static Log log = LogFactory.getLog(StoreResource.class); @@ -107,6 +116,9 @@ public abstract class StoreResource extends ResourceImpl { /** Send notifications under load */ private boolean sendNotificationsOnLoad = true; + + /** The load strategy */ + private String loadStrategy = SET_ERESOURCE; /** * The constructor, gets an uri and retrieves the backing OJBStore @@ -114,6 +126,11 @@ public abstract class StoreResource extends ResourceImpl { public StoreResource(URI uri) { super(uri); + final HashMap params = decodeQueryString(uri.query()); + if (params.get(LOAD_STRATEGY_PARAM) != null) { + loadStrategy = (String)params.get(LOAD_STRATEGY_PARAM); + } + if (log.isDebugEnabled()) { log.debug("Created " + this.getClass().getName() + " using uri: " + uri.toString()); } @@ -229,29 +246,27 @@ public abstract class StoreResource extends ResourceImpl { return; String option; - if (options != null && (option = (String)options.get(XMLResource.OPTION_DISABLE_NOTIFY)) != null) { + if (options != null && (option = (String) options.get(XMLResource.OPTION_DISABLE_NOTIFY)) != null) { sendNotificationsOnLoad = "false".compareToIgnoreCase(option) == 0; - } else if (options != null && (option = (String)options.get(XMIResource.OPTION_DISABLE_NOTIFY)) != null) { + } else if (options != null && (option = (String) options.get(XMIResource.OPTION_DISABLE_NOTIFY)) != null) { sendNotificationsOnLoad = "false".compareToIgnoreCase(option) == 0; } else { sendNotificationsOnLoad = true; } + + if (options != null && options.get(LOAD_STRATEGY_PARAM) != null) { + loadStrategy = (String)options.get(LOAD_STRATEGY_PARAM); + } isLoading = true; try { clearChangeTrackerArrays(); List list = loadResource(options); - // get from the superclass otherwise infinite looping - final Iterator it = list.iterator(); while (it.hasNext()) { - // fill in the resource, do not use the normal add method because it - // is possible that a child of a container is loaded, in that case - // the normal add will remove the container of the object when the - // resource is set in the child object, this issue can happen with - // direct reads using queries. - addToResource(it.next()); + final InternalEObject eObject = (InternalEObject)it.next(); + addToContent(eObject); } } finally { isLoading = false; @@ -259,24 +274,16 @@ public abstract class StoreResource extends ResourceImpl { } } - /** Add to the resource and dispatch if send notification */ - public void addToResource(Object obj) { + /** Add to this resource */ + protected void addToContent(InternalEObject eObject) { + setEResource(eObject, true); final ContentsEList elist = (ContentsEList) super.getContents(); - - if (elist.contains(obj)) { - return; // can maybe happen with extents? - } - - // already part of this resource - if (false && ((EObject)obj).eResource() == this) { - return; - } - - final NotificationChain notification = elist.basicAdd(obj, null); - StoreUtil.setEResource((InternalEObject) obj, this, true); - attached((EObject) obj); - if (sendNotificationsOnLoad && notification != null) { - notification.dispatch(); + if (!elist.contains(eObject)) { + final NotificationChain notifications = elist.basicAdd(eObject, null); + if (notifications != null && sendNotificationsOnLoad) { + notifications.dispatch(); + } + attached(eObject); } } @@ -333,7 +340,6 @@ public abstract class StoreResource extends ResourceImpl { // ensure that the resource is set correctly before validating if (obj.eResource() != this) { - Resource res = obj.eResource(); assert (obj.eResource() == this); } EContainerRepairControl.setEResourceToAlLContent((InternalEObject) obj, this); @@ -437,7 +443,9 @@ public abstract class StoreResource extends ResourceImpl { return; } - assert (loadedEObjects.contains(eObject)); + if (!loadedEObjects.contains(eObject)) { + assert (loadedEObjects.contains(eObject)); + } assert (!removedEObjects.contains(eObject)); removedEObjects.add(eObject); loadedEObjects.remove(eObject); @@ -463,8 +471,17 @@ public abstract class StoreResource extends ResourceImpl { /** * Attached the object to this resource, This object will be stored at the next save action. Also handles the * specific id generation used for different resource impl. + * + * Note that this method does not add the object to the resource.getContents(). It just adds the object to the + * internal lists of this resource. */ protected void attachedHelper(EObject eObject) { + // also attach the container + if (eObject.eContainer() != null && eObject.eContainer().eResource() == null && + !eObject.eContainmentFeature().isResolveProxies()) { + attached(eObject.eContainer()); + } + // a bit strange as an object can only be contained once but this can happen if someone // adds an object to a resource directly and then later add this same object as a child // to a container @@ -478,6 +495,23 @@ public abstract class StoreResource extends ResourceImpl { addedEObject(eObject); + if (eObject instanceof InternalEObject && eObject.eResource() == null) { + setEResource((InternalEObject)eObject, false); + } + + // only add an eobject to contents if it does not have a container or if the container + // relation allows resolve proxies (container and contained can be in different resources) + // and the load strategy is correct + if ((eObject.eContainer() == null || eObject.eContainmentFeature() == null || + eObject.eContainmentFeature().isResolveProxies()) && !getSuperContents().contains(eObject) && + loadStrategy.compareTo(ADD_TO_CONTENTS) == 0) { + final ContentsEList elist = (ContentsEList) super.getContents(); + final NotificationChain notifications = elist.basicAdd(eObject, null); + if (notifications != null && sendNotificationsOnLoad) { + notifications.dispatch(); + } + } + if (isTrackingModification()) { eObject.eAdapters().add(modificationTrackingAdapter); } @@ -489,23 +523,93 @@ public abstract class StoreResource extends ResourceImpl { map.put(id, eObject); } } - - if (eObject instanceof InternalEObject && eObject.eResource() == null) { - StoreUtil.setEResource((InternalEObject) eObject, this, false); - } - - // now also attach all ereferences with single values + + // now also attach all ereferences with single values which are contained for (Iterator it = eObject.eClass().getEAllReferences().iterator(); it.hasNext();) { final EReference eref = (EReference) it.next(); if (!eref.isMany() && eObject.eGet(eref) != null) { // the ismanies are handled differently final Resource res = ((EObject) eObject.eGet(eref)).eResource(); if (res == null) { // attach it to this resource because it has no other - attached((EObject) eObject.eGet(eref)); + final InternalEObject referedTo = (InternalEObject) eObject.eGet(eref); + attached(referedTo); } } } } + /** + * Add to the contents of this resource and dispatch if send notification. It also takes care of attaching this + * object and its contained children to the internal lists and setting the eResource. + * + * Approaches: + * - Set eResource and add to contents (if no econtainer) + * - Just set eResource and add to contents if it does not have a container + public void addToResource(InternalEObject eObject, boolean forceAddToContents) { + // if it has an econtainer then also add the econtainer + if (eObject.eContainer() != null && eObject.eContainer().eResource() == null) { + addToResource((InternalEObject)eObject.eContainer(), false); + } + + // if the econtainer is already part of this resource then just attach + if (!forceAddToContents && eObject.eContainer() != null && eObject.eContainer().eResource() == this) { + attached(eObject); + return; + } + + // probably lazy load action of non-containment, already part of this just return + if (!forceAddToContents && eObject.eResource() == this && !loadedEObjects.contains(eObject) && + !removedEObjects.contains(eObject) && !newEObjects.contains(eObject)) { + attached(eObject); + return; + } + + // already part of another resource + if (!forceAddToContents && eObject.eResource() != null) { + return; + } + + final ContentsEList elist = (ContentsEList) super.getContents(); + if (elist.contains(eObject)) { + // can happen because of extends, polymorphism + return; + } + + // fill in the resource, do not use the normal add method because it + // is possible that a child of a container is loaded, in that case + // the normal add will remove the container of the object when the + // resource is set in the child object, this issue can happen with + // direct reads using queries. + NotificationChain notification = null; + if (loadStrategy.compareToIgnoreCase(ADD_TO_CONTENTS) == 0 || forceAddToContents) { + notification = elist.basicAdd(eObject, null); + } + if (eObject.eResource() == null || (forceAddToContents && eObject.eResource() != this)) { + setEResource(eObject, forceAddToContents); + } +// attached(eObject); + if (sendNotificationsOnLoad && notification != null) { + notification.dispatch(); + } + } + */ + + /** + * Sets the eresource by walking up the containment structure and finding the highest parent. There the resource is + * set.If the resource is already set nothing is done. + */ + public void setEResource(InternalEObject eobj, boolean force) { + if (eobj.eResource() != null && eobj.eResource() != this && !force) + return; + + InternalEObject currentEObject = eobj; + while (currentEObject.eContainer() != null && !currentEObject.eContainmentFeature().isResolveProxies()) { + currentEObject = (InternalEObject) currentEObject.eContainer(); + } + if (currentEObject.eResource() != this) { + currentEObject.eSetResource(this, null); + } + } + /** Overridden to also support persistence specific id instead of single emf id */ protected void detachedHelper(EObject eObject) { diff --git a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/util/StoreUtil.java b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/util/StoreUtil.java index 34286ef89..790afeaae 100644 --- a/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/util/StoreUtil.java +++ b/plugins/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/util/StoreUtil.java @@ -12,7 +12,7 @@ * * </copyright> * - * $Id: StoreUtil.java,v 1.9 2006/11/25 23:52:18 mtaal Exp $ + * $Id: StoreUtil.java,v 1.10 2006/11/28 06:13:36 mtaal Exp $ */ package org.eclipse.emf.teneo.util; @@ -30,46 +30,33 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.notify.impl.NotificationImpl; -import org.eclipse.emf.common.notify.impl.NotifyingListImpl; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcorePackage; -import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.emf.ecore.EPackage.Registry; -import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.ExtendedMetaData; import org.eclipse.emf.ecore.util.FeatureMapUtil; import org.eclipse.emf.teneo.Constants; import org.eclipse.emf.teneo.ERuntime; -import org.eclipse.emf.teneo.PersistenceOptions; import org.eclipse.emf.teneo.StoreException; -import org.eclipse.emf.teneo.resource.StoreResource; /** * Contains different util methods. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> - * @version $Revision: 1.9 $ + * @version $Revision: 1.10 $ */ public class StoreUtil { - /** The EObject eclass */ - public static EClass EOBJECT_ECLASS = (EClass) EcorePackage.eINSTANCE.getEClassifier("EObject"); - - public static String EOBJECT_ECLASS_URI = EcorePackage.eINSTANCE.getNsURI() + "/" + EOBJECT_ECLASS.getName(); - /** The logger */ private static Log log = LogFactory.getLog(StoreUtil.class); @@ -86,7 +73,7 @@ public class StoreUtil { public static final String ANNOTATION_SOURCE = "http:///org/eclipse/emf/ecore/util/ExtendedMetaData"; /** The nsprefix, eclass separator */ - private static final String NSPREFIX_ECLASS_SEPARATOR = "."; + //private static final String NSPREFIX_ECLASS_SEPARATOR = "."; /** Returns the name of the entity used for this feature map entry */ public static String getEntityName(EStructuralFeature feature) { @@ -101,7 +88,7 @@ public class StoreUtil { return efeature.getEContainingClass().getName() + "/" + efeature.getName(); } - /** Translates an ECLass to a string representation */ + /** Translates an ECLass to a string representation public static String getEClassURI(EClass eclass, String qualify) { if (eclass == EOBJECT_ECLASS) { return EOBJECT_ECLASS_URI; @@ -116,7 +103,6 @@ public class StoreUtil { /** * Returns an estructuralfeature on the basis of the name of the eclass and the name of the feature itself. - */ public static EStructuralFeature getEStructuralFeature(String eclassURI, String featureName, EPackage[] epackages) { EClass eclass = getEClassFromURI(eclassURI, epackages); if (eclass == null) @@ -124,7 +110,8 @@ public class StoreUtil { return eclass.getEStructuralFeature(featureName); } - /** Translates an eclass uri back to an eclass */ + /* + /** Translates an eclass uri back to an eclass / public static EClass getEClassFromURI(String theEClassURI) { final Registry packageRegistry = Registry.INSTANCE; final EPackage[] epacks = new EPackage[packageRegistry.size()]; @@ -136,16 +123,16 @@ public class StoreUtil { return getEClassFromURI(theEClassURI, epacks); } - /** Translates an eclass uri back to an eclass */ - public static EClass getEClassFromURI(String theEClassURI, EPackage[] epackages) { + /** Translates an eclass uri back to an eclass / + public static EClass getEClassFromURI(String theEClassURI, EPackage[] epackages, EClassNameStrategy nameStrategy) { if (theEClassURI.compareTo(EOBJECT_ECLASS_URI) == 0) { return EcorePackage.eINSTANCE.getEObject(); } String nsPrefix = null; String eClassName = theEClassURI; if (eClassName.indexOf(NSPREFIX_ECLASS_SEPARATOR) != -1) { - nsPrefix = theEClassURI.substring(0, eClassName.indexOf(NSPREFIX_ECLASS_SEPARATOR)); - eClassName = theEClassURI.substring(1 + eClassName.indexOf(NSPREFIX_ECLASS_SEPARATOR)); + nsPrefix = theEClassURI.substring(0, eClassName.lastIndexOf(NSPREFIX_ECLASS_SEPARATOR)); + eClassName = theEClassURI.substring(1 + eClassName.lastIndexOf(NSPREFIX_ECLASS_SEPARATOR)); } ArrayList eclasses = new ArrayList(); @@ -189,9 +176,9 @@ public class StoreUtil { * final EClass eclass = (EClass)epack.getEClassifier(name); if (eclass == null) { throw new * StoreAnnotationsException("The nsuri " + nsuri + " and eclassname: " + name + " does not resolve to an * EClass"); } return eclass; - */ + / } - +*/ /** Sends out a notification of an elist load */ public static void dispatchEListLoadNotification(final EObject notifier, final EList elist, final EStructuralFeature feature) { @@ -249,25 +236,6 @@ public class StoreUtil { return false; } - /** - * Sets the eresource by walking up the containment structure and finding the highest parent. There the resource is - * set.If the resource is already set nothing is done. - */ - public static void setEResource(InternalEObject eobj, Resource.Internal resource, boolean force) { - if (eobj.eResource() != null && eobj.eResource() != resource && !force) - return; - if (eobj.eResource() == resource) { - return; - } - - InternalEObject currentEObject = eobj; - while (currentEObject.eContainer() != null && !currentEObject.eContainmentFeature().isResolveProxies()) { - currentEObject = (InternalEObject) currentEObject.eContainer(); - AssertUtil.assertNotSameObject(currentEObject, currentEObject.eContainer()); - } - currentEObject.eSetResource(resource, null); - } - /** Translates a string to a structural feature */ public static EStructuralFeature stringToStructureFeature(String strid) { // this method expects a dbid consisting of three parts separated by / @@ -380,8 +348,10 @@ public class StoreUtil { if (reserve != null) return reserve; - throw new StoreException("The fieldname " + fieldName + " is not present as a ereference type in the class: " - + eclass.getName()); + return null; + +// throw new StoreException("The fieldname " + fieldName + " is not present as a ereference type in the class: " +// + eclass.getName()); } /** |