You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2006/07/29 01:48:18 UTC

svn commit: r426710 [6/6] - in /incubator/openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/sr...

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java Fri Jul 28 16:48:13 2006
@@ -129,9 +129,7 @@
                         attachField(manager, toAttach, sm, fmds[i], true);
                         break;
                     case DETACH_FGS:
-                        if (fmds[i].isInDefaultFetchGroup()
-                            || fetch.hasAnyFetchGroup(fmds[i].getFetchGroups())
-                            || fetch.hasField(fmds[i].getFullName()))
+                        if (fetch.requiresFetch(fmds[i]))
                             attachField(manager, toAttach, sm, fmds[i], true);
                         break;
                     case DETACH_LOADED:

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java Fri Jul 28 16:48:13 2006
@@ -114,6 +114,7 @@
     // the repository this class belongs to, if any, and source file
     private final MetaDataRepository _repos;
     private final ValueMetaData _owner;
+    private final LifecycleMetaData _lifeMeta = new LifecycleMetaData(this);
     private ClassLoader _loader = null;
     private File _srcFile = null;
     private int _srcType = SRC_OTHER;
@@ -128,6 +129,7 @@
     private boolean _defSupFields = false;
     private Collection _staticFields = null;
     private int[] _fieldDataTable = null;
+    private Map _fgMap = null;
 
     ////////////////////////////////////////////////////////////////////
     // Note: if you add additional state, make sure to add it to copy()
@@ -144,7 +146,6 @@
 
     private String _seqName = DEFAULT_STRING;
     private SequenceMetaData _seqMeta = null;
-    private Map _fgs = new HashMap();
     private String _cacheName = DEFAULT_STRING;
     private int _cacheTimeout = Integer.MIN_VALUE;
     private Boolean _detachable = null;
@@ -166,8 +167,8 @@
     private FieldMetaData[] _definedFields = null;
     private FieldMetaData[] _listingFields = null;
     private FieldMetaData[] _allListingFields = null;
-
-    private final LifecycleMetaData _lifeMeta = new LifecycleMetaData(this);
+    private FetchGroup[] _fgs = null;
+    private FetchGroup[] _customFGs = null;
 
     /**
      * Constructor. Supply described type and repository.
@@ -1493,8 +1494,7 @@
             ClassMetaData meta = _repos.getMetaData(_type, _loader, true);
             meta.resolve(MODE_META);
             copy(this, meta);
-            _embedded =
-                Boolean.FALSE; // embedded instance isn't embedded-only
+            _embedded = Boolean.FALSE; // embedded instance isn't embedded-only
         }
 
         // make sure superclass is resolved
@@ -1550,6 +1550,11 @@
         // resolve lifecycle metadata now to prevent lazy threading problems
         _lifeMeta.resolve();
 
+        // resolve fetch groups
+        if (_fgMap != null)
+            for (Iterator itr = _fgMap.values().iterator(); itr.hasNext();)
+                ((FetchGroup) itr.next()).resolve();
+
         // if this is runtime, create a pc instance and scan it for comparators
         if (runtime && !Modifier.isAbstract(_type.getModifiers())) {
             ProxySetupStateManager sm = new ProxySetupStateManager();
@@ -1910,27 +1915,46 @@
         }
     }
 
-    /////////////////////
+    ///////////////
     // Fetch Group
-    /////////////////////
+    ///////////////
 
     /**
-     * Adds fecth group of the given name.
-     *
-     * @param name a non-null, non-empty name. Must be unique within this
-     * receiver's scope. The super class <em>may</em> have a group with
-     * the same name.
+     * Return the fetch groups declared explicitly in this type.
      */
-    public synchronized FetchGroup addFetchGroup(String name) {
-    	if (name == null || name.trim().length()==0)
-    		throw new MetaDataException(_loc.get("empty-fg-name", this));
-        FetchGroup fg = (FetchGroup) _fgs.get(name);
-        if (fg == null) {
-        	fg = new FetchGroup(this, name);
-        	_fgs.put(name, fg);
-        }
+    public FetchGroup[] getDeclaredFetchGroups() {
+        if (_fgs == null)
+            _fgs = (_fgMap == null) ? new FetchGroup[0] : (FetchGroup[])
+                _fgMap.values().toArray(new FetchGroup[_fgMap.size()]); 
+        return _fgs;
+    }
 
-        return fg;
+    /**
+     * Return all fetch groups for this type, including superclass groups.
+     */
+    public FetchGroup[] getCustomFetchGroups() {
+        if (_customFGs == null) {
+            // map fgs to names, allowing our fgs to override supers
+            Map fgs = new HashMap();
+            ClassMetaData sup = getPCSuperclassMetaData();
+            if (sup != null)
+            {
+                FetchGroup[] supFGs = sup.getCustomFetchGroups();
+                for (int i = 0; i < supFGs.length; i++)
+                    fgs.put(supFGs[i].getName(), supFGs[i]);
+            }
+            FetchGroup[] decs = getDeclaredFetchGroups();
+            for (int i = 0; i < decs.length; i++)
+                fgs.put(decs[i].getName(), decs[i]);
+            
+            // remove std groups
+            fgs.remove(FetchGroup.NAME_DEFAULT);
+            fgs.remove(FetchGroup.NAME_ALL);
+
+            _customFGs = (FetchGroup[]) fgs.values().toArray
+                (new FetchGroup[fgs.size()]);
+        }
+        return _customFGs;
     }
 
     /**
@@ -1941,16 +1965,56 @@
      * @return an existing fecth group of the given name if known to this 
      * receiver or any of its superclasses. Otherwise null.
      */
-    public synchronized FetchGroup getFetchGroup(String name) {
-        FetchGroup fg = (FetchGroup) _fgs.get(name);
+    public FetchGroup getFetchGroup(String name) {
+        FetchGroup fg = (_fgMap == null) ? null : (FetchGroup) _fgMap.get(name);
+        if (fg != null)
+            return fg;
+        ClassMetaData sup = getPCSuperclassMetaData();
+        if (sup != null)
+            return sup.getFetchGroup(name);
+        if (FetchGroup.NAME_DEFAULT.equals(name))
+            return FetchGroup.DEFAULT;
+        if (FetchGroup.NAME_ALL.equals(name))
+            return FetchGroup.ALL;
+        return null;
+    }
+
+    /**
+     * Adds fetch group of the given name, or returns existing instance.
+     *
+     * @param name a non-null, non-empty name. Must be unique within this
+     * receiver's scope. The super class <em>may</em> have a group with
+     * the same name.
+     */
+    public FetchGroup addDeclaredFetchGroup(String name) {
+    	if (StringUtils.isEmpty(name))
+    		throw new MetaDataException(_loc.get("empty-fg-name", this));
+        if (_fgMap == null)
+            _fgMap = new HashMap();
+        FetchGroup fg = (FetchGroup) _fgMap.get(name);
         if (fg == null) {
-            ClassMetaData scm = getPCSuperclassMetaData();
-            if (scm != null)
-                fg = scm.getFetchGroup(name);
+        	fg = new FetchGroup(this, name);
+        	_fgMap.put(name, fg);
+            _fgs = null;
+            _customFGs = null;
         }
         return fg;
     }
 
+    /**
+     * Remove a declared fetch group.
+     */
+    public boolean removeDeclaredFetchGroup(FetchGroup fg) {
+        if (fg == null)
+            return false;
+        if (_fgMap.remove(fg.getName()) != null) {
+            _fgs = null;
+            _customFGs = null;
+            return true;
+        }
+        return false;
+    }
+
     /////////////////
     // SourceTracker
     /////////////////
@@ -2082,6 +2146,14 @@
             field.setDeclaredIndex(-1);
             field.setIndex(-1);
             field.copy(fields[i]);
+        }
+
+        // copy fetch groups
+        FetchGroup[] fgs = meta.getDeclaredFetchGroups();
+        FetchGroup fg;
+        for (int i = 0; i < fgs.length; i++) {
+            fg = addDeclaredFetchGroup(fgs[i].getName());
+            fg.copy(fgs[i]); 
         }
     }
 

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java Fri Jul 28 16:48:13 2006
@@ -1,21 +1,20 @@
 /*
  * Copyright 2006 The Apache Software Foundation.
- *  Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *  http://www.apache.org/licenses/LICENSE-2.0
- *  Unless required by applicable law or agreed to in writing, software
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/**
- * 
- */
 package org.apache.openjpa.meta;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -23,151 +22,322 @@
 import java.util.Map;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.lib.meta.SourceTracker;
+import org.apache.commons.lang.ObjectUtils;
 import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.UserException;
+import org.apache.openjpa.util.MetaDataException;
+import serp.util.Numbers;
 
 /**
  * Captures fetch group metadata.
  */
-public class FetchGroup implements SourceTracker {
+public class FetchGroup {
+
+    /**
+     * Name of the default fetch group.
+     */
+    public static final String NAME_DEFAULT = "default";
+
+    /**
+     * Name of the "all" fetch group.
+     */
+    public static final String NAME_ALL = "all";
+
+    /**
+     * Default field recursion depth.
+     */
+    public static final int RECURSION_DEPTH_DEFAULT = 1;
+
+    /**
+     * Infinite depth.
+     */
+	public static final int DEPTH_INFINITE = -1;
+
+    /**
+     *  Standard default fetch group.
+     */
+    static final FetchGroup DEFAULT = new FetchGroup(NAME_DEFAULT, true);
+
+    /**
+     *  Standard "all" fetch group.
+     */
+    static final FetchGroup ALL = new FetchGroup(NAME_ALL, false);
+
+    private static final Localizer _loc = Localizer.forPackage
+        (FetchGroup.class);
 
     private final String _name;
-    private final ClassMetaData _declaringClass;
+    private final ClassMetaData _meta;
+    private final boolean _readOnly;
     private List _includes;
-    private Map  _depths;
-    private boolean _postLoad;
-    public static final int DEFAULT_RECURSION_DEPTH = 1;
-    private static final Localizer _loc =
-        Localizer.forPackage(FetchGroup.class);
+    private Map _depths;
+    private Boolean _postLoad;
 
     /**
-     * Supply immutable name.
+     * Constructor; supply immutable name.
      *
-     * @param must not by null or empty.
+     * @param name must not by null or empty.
      */
     FetchGroup(ClassMetaData cm, String name) {
-        super();
-        if (StringUtils.isEmpty(name))
-            throw new UserException(_loc.get("invalid-fg-name", cm, name));
+        _meta = cm;
+        _name = name;
+        _readOnly = false;
+    }
+
+    /**
+     * Internal constructor for builtin fetch groups.
+     */
+    private FetchGroup(String name, boolean postLoad) {
+        _meta = null;
         _name = name;
-        _declaringClass = cm;
+        _postLoad = (postLoad) ? Boolean.TRUE : Boolean.FALSE;
+        _readOnly = true;
+    }
+
+    /**
+     * Copy state from the given fetch group.
+     */
+    void copy(FetchGroup fg) {
+        if (fg._includes != null)
+            for (Iterator itr = fg._includes.iterator(); itr.hasNext();)
+                addDeclaredInclude((String) itr.next());
+        if (fg._depths != null) {
+            Map.Entry entry;
+            for (Iterator itr = fg._depths.entrySet().iterator(); 
+                itr.hasNext();) {
+                entry = (Map.Entry) itr.next();
+                setRecursionDepth((FieldMetaData) entry.getKey(), ((Number) 
+                    entry.getValue()).intValue());
+            }
+        }
+        if (fg._postLoad != null)
+            _postLoad = fg._postLoad;
     }
 
+    /**
+     * Fetch group name.
+     */
     public String getName() {
         return _name;
     }
 
     /**
      * Includes given fetch group within this receiver.
-     *
-     * @param fg must not be null or this receiver itself or must not include
-     *           this receiver.
      */
-    public void addInclude(FetchGroup fg) {
-        if (fg == this)
-            throw new UserException(_loc.get("self-include-fg", this));
-        if (fg == null)
-            throw new UserException(_loc.get("null-include-fg", this));
-        if (fg.includes(this, true))
-            throw new UserException(_loc.get("cyclic-fg", this, fg));
+    public void addDeclaredInclude(String fgName) {
+        if (_readOnly)
+            throw new UnsupportedOperationException();
+        if (StringUtils.isEmpty(fgName))
+            throw new MetaDataException(_loc.get("null-include-fg", this));
         if (_includes == null)
             _includes = new ArrayList();
-        _includes.add(fg);
+        if (!_includes.contains(fgName))
+            _includes.add(fgName);
     }
 
     /**
-     * Affirms if given fetch group is included by this receiver.
+     * Affirms if given fetch group is included by this receiver.  Includes
+     * superclass definition of fetch group and optionally other included 
+     * groups.
      *
-     * @param fg
      * @param recurse if true then recursively checks within the included
-     *                fecth groups. Otherwise just checks within direct includes.
-     * @return
+     * fecth groups
      */
-    public boolean includes(FetchGroup fg, boolean recurse) {
-        if (_includes == null)
-            return false;
-        if (_includes.contains(fg))
-            return true;
-        if (recurse)
-            for (Iterator i = _includes.iterator(); i.hasNext();)
-                if (((FetchGroup) i.next()).includes(fg, true))
-                    return true;
+    public boolean includes(String fgName, boolean recurse) {
+        // check our includes
+        if (_includes != null) {
+            if (_includes.contains(fgName))
+                return true;
+            if (recurse) {
+                FetchGroup fg;
+                for (Iterator i = _includes.iterator(); i.hasNext();) {
+                    fg = _meta.getFetchGroup((String) i.next());
+                    if (fg != null && fg.includes(fgName, true))
+                        return true;
+                }
+            }
+        }
+        if (_meta != null) {
+            // check superclass includes
+            ClassMetaData sup = _meta.getPCSuperclassMetaData();
+            if (sup != null) {
+                FetchGroup supFG = sup.getFetchGroup(_name);
+                if (supFG != null)
+                    return supFG.includes(fgName, recurse);
+            }
+        }
         return false;
     }
 
     /**
-     * Sets recursion depth for a field.
-     *
-     * @param fm
-     * @param depth
+     * Return the fetch group names declared included by this group.
      */
-    public void setDepthFor(FieldMetaData fm, int depth) {
+    public String[] getDeclaredIncludes() {
+        // only used during serialization; no need to cache
+        return (_includes == null) ? new String[0]
+            : (String[]) _includes.toArray(new String[_includes.size()]);
+    }
+
+    /**
+     * Recursion depth for the given field.  This is the depth of relations of
+     * the same class as this one we can fetch through the given field.
+     */
+    public void setRecursionDepth(FieldMetaData fm, int depth) {
+        if (_readOnly)
+            throw new UnsupportedOperationException();
         if (depth < -1)
-            throw new UserException(_loc.get("invalid-fetch-depth",
-                _name, fm, new Integer(depth)));
+            throw new MetaDataException(_loc.get("invalid-fg-depth", _name, fm, 
+                Numbers.valueOf(depth)));
         if (_depths == null)
             _depths = new HashMap();
-        _depths.put(fm, new Integer(depth));
+        _depths.put(fm, Numbers.valueOf(depth));
     }
 
     /**
-     * Gets recusrion depth for the given field.
-     *
-     * @param fm
-     * @return defaults to 1.
+     * Recursion depth for the given field.  This is the depth of relations of
+     * the same class as this one we can fetch through the given field.
      */
-    public int getDepthFor(FieldMetaData fm) {
-        if (_depths == null || !_depths.containsKey(fm))
-            return DEFAULT_RECURSION_DEPTH;
-        return ((Integer) _depths.get(fm)).intValue();
+    public int getRecursionDepth(FieldMetaData fm) {
+        Number depth = findRecursionDepth(fm);
+        return (depth == null) ? RECURSION_DEPTH_DEFAULT : depth.intValue();
     }
 
-    
-    public boolean isPostLoad () {
-    	return _postLoad;
+    /**
+     * Return the recursion depth declared for the given field, or 
+     * 0 if none.
+     */
+    public int getDeclaredRecursionDepth(FieldMetaData fm) {
+        Number depth = (_depths == null) ? null : (Number) _depths.get(fm);
+        return (depth == null) ? 0 : depth.intValue();
+    }
+
+    /**
+     * Helper to find recursion depth recursively in our includes.
+     */
+    private Number findRecursionDepth(FieldMetaData fm) { 
+        Number depth = (_depths == null) ? null : (Number) _depths.get(fm);
+        if (depth != null)
+            return depth;
+
+        // check for superclass declaration of depth
+        Number max = null;
+        if (_meta != null && fm.getDeclaringMetaData() != _meta) {
+            ClassMetaData sup = _meta.getPCSuperclassMetaData();
+            if (sup != null) {
+                FetchGroup supFG = sup.getFetchGroup(_name);
+                if (supFG != null)
+                    max = supFG.findRecursionDepth(fm);
+            }
+        }
+        if (_includes == null)
+            return max;
+
+        // find largest included depth
+        FetchGroup fg;
+        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
+            fg = _meta.getFetchGroup((String) itr.next());
+            depth = (fg == null) ? null : fg.findRecursionDepth(fm);
+            if (depth != null && (max == null 
+                || depth.intValue() > max.intValue()))
+                max = depth;
+        }
+        return max;
     }
 
+    /**
+     * Return the fields with declared recursion depths in this group.
+     */
+    public FieldMetaData[] getDeclaredRecursionDepthFields() {
+        // used in serialization only; no need to cache
+        if (_depths == null)
+            return new FieldMetaData[0];
+         return (FieldMetaData[]) _depths.keySet().toArray
+            (new FieldMetaData[_depths.size()]);
+    } 
+
+    /**
+     * Whether loading this fetch group causes a post-load callback on the
+     * loaded instance.
+     */
     public void setPostLoad (boolean flag) {
-    	_postLoad = flag;
+        if (_readOnly && flag != isPostLoad())
+            throw new UnsupportedOperationException();
+    	_postLoad = (flag) ? Boolean.TRUE : Boolean.FALSE;
     }
-    
+
     /**
-     * Affirms equality if the other has the same name.
+     * Whether loading this fetch group causes a post-load callback on the
+     * loaded instance.
      */
-    public boolean equals(Object other) {
-        if (other instanceof FetchGroup) {
-            FetchGroup that = (FetchGroup) other;
-            return _name.equals(that._name)
-                && _declaringClass.equals(that._declaringClass);
+    public boolean isPostLoad () {
+    	if (_postLoad != null)
+            return _postLoad.booleanValue();
+
+        if (_meta != null) {
+            ClassMetaData sup = _meta.getPCSuperclassMetaData();
+            FetchGroup supFG = sup.getFetchGroup(_name);
+            if (supFG != null && supFG.isPostLoad())
+                return true;
+        }
+
+        if (_includes == null)
+            return false;
+        FetchGroup fg;
+        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
+            fg = _meta.getFetchGroup((String) itr.next());
+            if (fg != null && fg.isPostLoad())
+                return true;
         }
         return false;
     }
 
-    public int hashCode() {
-        return _name.hashCode() + _declaringClass.hashCode();
+    /**
+     * Whether the post-load value is declared for this group.  
+     */
+    public boolean isPostLoadExplicit() {
+        return _postLoad != null;
     }
 
-    public String toString() {
-        return _name;
-    }
+    /**
+     * Resolve and validate fetch group metadata.
+     */
+    public void resolve() {
+        if (_includes == null)
+            return;
 
-    /////////////////
-    // SourceTracker
-    /////////////////
-    public File getSourceFile() {
-        return _declaringClass.getSourceFile();
+        // validate includes
+        String name;
+        FetchGroup fg;
+        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
+            name = (String) itr.next();
+            if (name.equals(_name))
+                throw new MetaDataException(_loc.get("cyclic-fg", this, name));
+            fg = _meta.getFetchGroup(name);
+            if (fg == null)
+                throw new MetaDataException(_loc.get("bad-fg-include", this,
+                    name));
+            if (fg.includes(_name, true))
+                throw new MetaDataException(_loc.get("cyclic-fg", this, name));
+        }
     }
-
-    public Object getSourceScope() {
-        return _declaringClass;
+    
+    /**
+     * Affirms equality if the other has the same name and declaring type.
+     */
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (!(other instanceof FetchGroup))
+            return false;
+        FetchGroup that = (FetchGroup) other;
+        return _name.equals(that._name)
+            && ObjectUtils.equals(_meta, that._meta);
     }
 
-    public int getSourceType() {
-        return _declaringClass.getSourceType();
+    public int hashCode() {
+        return _name.hashCode() + ((_meta == null) ? 0 : _meta.hashCode());
     }
 
-    public String getResourceName() {
-        return _declaringClass.getResourceName();
+    public String toString() {
+        return ((_meta == null) ? "Builtin" : _meta.toString ()) + "." + _name;
     }
 }

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java Fri Jul 28 16:48:13 2006
@@ -39,7 +39,6 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.kernel.FetchConfiguration;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.kernel.StoreContext;
 import org.apache.openjpa.lib.conf.Configurations;
@@ -110,7 +109,6 @@
     private static final int DFG_EXPLICIT = 4;
 
     private static final Method DEFAULT_METHOD;
-
     static {
         try {
             DEFAULT_METHOD = Object.class.getMethod("wait", (Class[]) null);
@@ -152,7 +150,8 @@
     private int _pkIndex = -1;
     private boolean _explicit = false;
     private int _dfg = 0;
-    private Set _fgs = null;
+    private Set _fgSet = null;
+    private String[] _fgs = null;
     private Boolean _lrs = null;
     private String _extName = null;
     private Method _extMethod = DEFAULT_METHOD;
@@ -554,6 +553,61 @@
     }
 
     /**
+     * Gets the name of the custom fetch groups those are associated to this 
+     * receiver.  This does not include the "default" and "all" fetch groups.
+     *
+     * @return the set of fetch group names, not including the default and
+     * all fetch groups.
+     */
+    public String[] getCustomFetchGroups() {
+        if (_fgs == null) {
+            if (_fgSet == null || _manage != MANAGE_PERSISTENT 
+                || isPrimaryKey() || isVersion())
+                _fgs = new String[0];
+            else
+                _fgs = (String[]) _fgSet.toArray(new String[_fgSet.size()]);
+        }
+        return _fgs;
+    }
+
+    /**
+     * Whether this field is in the given fetch group.
+     */
+    public boolean isInFetchGroup(String fg) {
+        if (_manage != MANAGE_PERSISTENT || isPrimaryKey() || isVersion())
+            return false;
+        if (FetchGroup.NAME_ALL.equals(fg))
+            return true;
+        if (FetchGroup.NAME_DEFAULT.equals(fg))
+            return isInDefaultFetchGroup();
+        return _fgSet != null && _fgSet.contains(fg);
+    }
+
+    /**
+     * Set whether this field is in the given fetch group.
+     *
+     * @param fg is the name of a fetch group that must be present in the
+     * class that declared this field or any of its persistent superclasses.
+     */
+    public void setInFetchGroup(String fg, boolean in) {
+        if (StringUtils.isEmpty(fg))
+            throw new MetaDataException(_loc.get("empty-fg-name", this));
+        if (fg.equals(FetchGroup.NAME_ALL))
+            return;
+        if (fg.equals(FetchGroup.NAME_DEFAULT)) {
+            setInDefaultFetchGroup(in);
+            return;
+        }
+        if (_owner.getFetchGroup(fg) == null)
+            throw new MetaDataException(_loc.get("unknown-fg", fg, this));
+        if (in && _fgSet == null)
+            _fgSet = new HashSet();
+        if ((in && _fgSet.add(fg))
+            || (!in && _fgSet != null && _fgSet.remove(fg)))
+            _fgs = null;
+    }
+
+    /**
      * How the data store should treat null values for this field:
      * <ul>
      * <li>{@link #NULL_UNSET}: no value supplied</li>
@@ -828,62 +882,6 @@
     }
 
     /**
-     * Gets the name of the fetch groups those are associated to this receiver.
-     *
-     * @return the set of fetch group names.
-     * null if this field is a primary key or a version field.
-     * zero-length array if no fetch group has been associated.
-     */
-    public Set getFetchGroups() {
-        if (isPrimaryKey() || isVersion())
-            return null;
-        if (_fgs == null)
-            return new HashSet();
-        return _fgs;
-    }
-
-    /**
-     * Add the fetch group of given name for this field.
-     *
-     * @param fg is the name of a fetch group that must be present in the
-     * class that declared this field or any of its persistent superclasses.
-     */
-    public void addFetchGroup(String fg) {
-        if (StringUtils.isEmpty(fg))
-            throw new MetaDataException(_loc.get("bad-fg", fg));
-        if (getDeclaringMetaData().getFetchGroup(fg) == null)
-            throw new MetaDataException(_loc.get("unknown-fg", fg));
-        if (_fgs == null)
-            _fgs = new HashSet();
-        _fgs.add(fg);
-        if (fg.equals(FetchConfiguration.FETCH_GROUP_DEFAULT))
-            setInDefaultFetchGroup(true);
-    }
-
-    public void removeFetchGroup(String fg) {
-        if (_fgs == null)
-            return;
-        _fgs.remove(fg);
-        if (FetchConfiguration.FETCH_GROUP_DEFAULT.equals(fg))
-            setInDefaultFetchGroup(false);
-    }
-
-    public boolean fetchGroupOverlapsWith(FieldMetaData that) {
-        Set other = that.getFetchGroups();
-        if (_fgs == null || other == null || other.isEmpty())
-            return false;
-
-        for (Iterator fg = _fgs.iterator(); fg.hasNext();)
-            if (other.contains(fg.next()))
-                return true;
-        return false;
-    }
-
-    public boolean isDeclaredInFetchGroup(String fg) {
-        return (_fgs != null && _fgs.contains(fg));
-    }
-
-    /**
      * Whether this field uses intermediate data when loading/storing
      * information through a {@link OpenJPAStateManager}. Defaults to true.
      *
@@ -1649,8 +1647,8 @@
             if (field.isDefaultFetchGroupExplicit())
                 _dfg |= DFG_EXPLICIT;
         }
-        if (_fgs == null)
-            _fgs = field.getFetchGroups();
+        if (_fgSet == null && field._fgSet != null)
+            _fgSet = new HashSet(field._fgSet);
         if (_lrs == null)
             _lrs = (field.isLRS()) ? Boolean.TRUE : Boolean.FALSE;
         if (_valStrategy == -1)

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java Fri Jul 28 16:48:13 2006
@@ -24,7 +24,6 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.FetchState;
 import org.apache.openjpa.kernel.LockManager;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.kernel.PCState;
@@ -97,15 +96,14 @@
         LockManager lm;
         for (Iterator itr = sms.iterator(); itr.hasNext();) {
             sm = (OpenJPAStateManager) itr.next();
-            FetchState fetchState = fetch.newFetchState();
             if (sm.getManagedInstance() == null) {
-                if (!store.initialize(sm, state, fetchState, context))
+                if (!store.initialize(sm, state, fetch, context))
                     failed = addFailedId(sm, failed);
             } else if (load != StoreManager.FORCE_LOAD_NONE
                 || sm.getPCState() == PCState.HOLLOW) {
                 lm = sm.getContext().getLockManager();
-                if (!store.load(sm, sm.getUnloaded(fetchState),
-                    fetchState, lm.getLockLevel(sm), context))
+                if (!store.load(sm, sm.getUnloaded(fetch), fetch, 
+                    lm.getLockLevel(sm), context))
                     failed = addFailedId(sm, failed);
             } else if (!store.exists(sm, context))
                 failed = addFailedId(sm, failed);

Added: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java?rev=426710&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java (added)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java Fri Jul 28 16:48:13 2006
@@ -0,0 +1,23 @@
+package org.apache.openjpa.util;
+
+import java.util.Map;
+
+import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Repository of store-specific facade classes. This is used by facade 
+ * implementations to wrap store-specific components without knowing 
+ * about all possible back-ends.
+ */
+public class StoreFacadeTypeRegistry {
+
+    private Map _impls = new ConcurrentHashMap();
+
+    public void registerImplementation(Class facadeType, Class implType) {
+        _impls.put(facadeType, implType);
+    }
+    
+    public Class getImplementation(Class facadeType) {
+        return (Class) _impls.get(facadeType);
+    }
+}

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties Fri Jul 28 16:48:13 2006
@@ -20,7 +20,7 @@
 found-pcs: Found {0} classes with metadata in {1} milliseconds.
 unmanaged-sup-field: Superclass field "{0}" is mapped in the metadata for \
 	subclass "{1}", but is not a persistent field.
-bad-discover-class: The class "{0}" listed in the org.apache.openjpa.MetaDataFactory \
+bad-discover-class: The class "{0}" listed in the openjpa.MetaDataFactory \
 	configuration property could not be loaded; ignoring.
 bad-lrs-concrete: Large result set fields must be of type java.util.Collection \
 	or java.util.Map.  No concrete classes or other interfaces are allowed. \
@@ -248,8 +248,12 @@
 mapped-unknownid: Type "{0}" is mapped to the data store, but does not have \
 	an identity type.  Alter its metadata to declare datastore identity or \
 	to have at least one primary key field.
-wrong-default-fg-name: Attempt to change default fetch group name to "{0}" \
-	from current name "{1}" is not permitted.
-duplicate-fg: Fetch group "{0}" is already defined in "{1}".
-invalid-fetch-depth: Fetch group "{0}" for field "{1}" specifies invalid \
-	recursion depth {2}. Recursion depth must be greater than or equal to -1.
+empty-fg-name: Attempt to add an unnamed fetch group to "{0}".
+invalid-fg-depth: Fetch group "{0}" specifies invalid recursion depth "{2}" \
+    for field "{1}". Recursion depth must be greater than or equal to -1.
+cyclic-fg: Attempt to include fetch group "{1}" in fetch group "{0}" creates \
+    an inclusion cycle.
+bad-fg-inclue: Attempt to include non-existent fetch group "{1}" in fetch \
+    group "{0}".
+unknown-fg: Attempt to add fetch group "{0}" to type field "{1}" failed. \
+    This fetch group has not been defined.

Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java (original)
+++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java Fri Jul 28 16:48:13 2006
@@ -860,28 +860,32 @@
      * Create fetch groups.
      */
     private void parseFetchGroups(ClassMetaData meta, FetchGroup... groups) {
+        org.apache.openjpa.meta.FetchGroup fg;
         for (FetchGroup group : groups) {
             if (StringUtils.isEmpty(group.name()))
                 throw new MetaDataException(_loc.get("unnamed-fg", meta));
-            meta.addFetchGroup(group.name());
+
+            fg = meta.addDeclaredFetchGroup(group.name());
+            if (group.postLoad())
+                fg.setPostLoad(true); 
             for (FetchAttribute attr : group.attributes())
-                parseFetchAttribute(meta, group.name(), attr);
+                parseFetchAttribute(meta, fg, attr);
         }
     }
 
     /**
      * Set a field's fetch group.
      */
-    private void parseFetchAttribute(ClassMetaData meta, String group,
-        FetchAttribute attr) {
+    private void parseFetchAttribute(ClassMetaData meta, 
+        org.apache.openjpa.meta.FetchGroup fg, FetchAttribute attr) {
         FieldMetaData field = meta.getDeclaredField(attr.name());
         if (field == null
             || field.getManagement() != FieldMetaData.MANAGE_PERSISTENT)
-            throw new MetaDataException(_loc.get("bad-fg-field", group,
+            throw new MetaDataException(_loc.get("bad-fg-field", fg.getName(),
                 meta, attr.name()));
 
-        // validations passed; set fetch group
-        field.addFetchGroup(group);
+        if (attr.recursionDepth() != Integer.MIN_VALUE)
+            fg.setRecursionDepth(field, attr.recursionDepth());
     }
 
     /**

Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchAttribute.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchAttribute.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchAttribute.java (original)
+++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchAttribute.java Fri Jul 28 16:48:13 2006
@@ -29,7 +29,13 @@
 @Retention(RUNTIME)
 public @interface FetchAttribute {
 
+    /**
+     * Included field/property name.
+     */
     String name() default "";
 
-    int depth() default 1;
+    /**
+     * Recursion depth for relation field.
+     */
+    int recursionDepth() default Integer.MIN_VALUE;
 }

Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchGroup.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchGroup.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchGroup.java (original)
+++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchGroup.java Fri Jul 28 16:48:13 2006
@@ -30,7 +30,18 @@
 @Retention(RUNTIME)
 public @interface FetchGroup {
 
+    /**
+     * Name of fetch group.
+     */
     String name() default "";
 
+    /**
+     * Whether loading this group results in a post-load callback.
+     */
+    boolean postLoad() default false;
+
+    /**
+     * Included attributes.
+     */
     FetchAttribute[] attributes() default {};
 }

Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java (original)
+++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java Fri Jul 28 16:48:13 2006
@@ -23,6 +23,7 @@
 
 import org.apache.openjpa.kernel.DelegatingFetchConfiguration;
 import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.meta.FetchGroup;
 
 /**
  * The fetch plan allows you to dynamically alter eager fetching
@@ -37,8 +38,17 @@
     /**
      * Fetch group representing all fields.
      */
-    public static final String FETCH_GROUP_ALL =
-        FetchConfiguration.FETCH_GROUP_ALL;
+    public static final String GROUP_ALL = FetchGroup.NAME_ALL;
+
+    /**
+     * The default fetch group.
+     */
+    public static final String GROUP_DEFAULT = FetchGroup.NAME_DEFAULT;
+
+    /**
+     * Infinite fetch depth.
+     */
+    public static final int DEPTH_INFINITE = FetchGroup.DEPTH_INFINITE;
 
     /**
      * Constant to revert any setting to its default value.
@@ -71,8 +81,23 @@
     }
 
     /**
+     * The maximum fetch depth when loading an object.
+     */
+    public int getMaxFetchDepth(int depth) {
+        return _fetch.getMaxFetchDepth();
+    }
+
+    /**
+     * The maximum fetch depth when loading an object.
+     */
+    public FetchPlan setMaxFetchDepth(int depth) {
+        _fetch.setMaxFetchDepth(depth);
+        return this;
+    }
+
+    /**
      * Return the fetch batch size for large result set support.
-     * Defaults to the	<code>org.apache.openjpa.FetchBatchSize</code> setting. Note
+     * Defaults to the	<code>openjpa.FetchBatchSize</code> setting. Note
      * that this property will be ignored under some data stores.
      */
     public int getFetchBatchSize() {
@@ -81,7 +106,7 @@
 
     /**
      * Set the fetch batch size for large result set support.
-     * Defaults to the	<code>org.apache.openjpa.FetchBatchSize</code> setting. Note
+     * Defaults to the	<code>openjpa.FetchBatchSize</code> setting. Note
      * that this property will be ignored under some data stores.
      */
     public FetchPlan setFetchBatchSize(int fetchBatchSize) {
@@ -116,7 +141,6 @@
      * <code>org.apache.openjpa.FetchGroups</code> setting.
      */
     public Collection<String> getFetchGroups() {
-//		return new FetchGroupSet ();
         return _fetch.getFetchGroups();
     }
 
@@ -195,7 +219,6 @@
      * will use when loading objects. Defaults to the empty set.
      */
     public Collection<String> getFields() {
-//		return new FetchFieldSet ();
         return (Collection<String>) _fetch.getFields();
     }
 
@@ -398,66 +421,4 @@
             return false;
         return _fetch.equals(((FetchPlan) other)._fetch);
     }
-
-    /**
-     * View of fetch groups as collection.
-     */
-//	private class FetchGroupSet
-//		extends AbstractCollection<String>
-//	{
-//		private String[] _groups = null;
-//
-//
-//		public boolean contains (Object o)
-//		{
-//			return o instanceof String && _fetch.hasFetchGroup ((String) o);
-//		}
-//
-//
-//		public Iterator iterator ()
-//		{
-//			if (_groups == null)
-//				_groups = _fetch.getFetchGroups ();
-//			return new ObjectArrayIterator (_groups);
-//		}
-//
-//
-//		public int size ()
-//		{
-//			if (_groups == null)
-//				_groups = _fetch.getFetchGroups ();
-//			return _groups.length;
-//		}
-//	}
-
-    /**
-     * View of fetch fields as collection.
-     */
-//	private class FetchFieldSet
-//		extends AbstractCollection<String>
-//	{
-//		private String[] _fields = null;
-//
-//
-//		public boolean contains (Object o)
-//		{
-//			return o instanceof String && _fetch.hasField ((String) o);
-//		}
-//
-//
-//		public Iterator iterator ()
-//		{
-//			if (_fields == null)
-//				_fields = _fetch.getFields ();
-//			return new ObjectArrayIterator (_fields);
-//		}
-//
-//
-//		public int size ()
-//		{
-//			if (_fields == null)
-//				_fields = _fetch.getFields ();
-//			return _fields.length;
-//		}
-//	}
 }

Modified: incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java (original)
+++ incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java Fri Jul 28 16:48:13 2006
@@ -25,7 +25,7 @@
 import java.util.Map;
 
 import org.apache.openjpa.event.OrphanedKeyAction;
-import org.apache.openjpa.kernel.FetchState;
+import org.apache.openjpa.kernel.FetchConfiguration;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.kernel.StoreContext;
 import org.apache.openjpa.meta.ClassMetaData;
@@ -105,17 +105,14 @@
      * given state manager. Only fields in the given fetch configuration are
      * loaded.
      */
-    public void load(OpenJPAStateManager sm, FetchState fetchState) {
+    public void load(OpenJPAStateManager sm, FetchConfiguration fetch) {
         if (sm.getVersion() == null)
             sm.setVersion(_version);
 
         FieldMetaData[] fmds = _meta.getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            if (fmds[i].getManagement() == fmds[i].MANAGE_PERSISTENT
-                && (fetchState.requiresLoad(sm, fmds[i]))) {
-                sm.store(i, toLoadable(sm, fmds[i], _data[i], fetchState));
-            }
-        }
+        for (int i = 0; i < fmds.length; i++)
+            if (!sm.getLoaded().get(i) && fetch.requiresFetch(fmds[i]))
+                sm.store(i, toLoadable(sm, fmds[i], _data[i], fetch));
     }
 
     /**
@@ -123,14 +120,14 @@
      * given state manager. Only fields in the given bit set will be loaded.
      */
     public void load(OpenJPAStateManager sm, BitSet fields,
-        FetchState fetchState) {
+        FetchConfiguration fetch) {
         if (sm.getVersion() == null)
             sm.setVersion(_version);
 
         FieldMetaData[] fmds = _meta.getFields();
         for (int i = 0; i < fmds.length; i++)
             if (fields.get(i))
-                sm.store(i, toLoadable(sm, fmds[i], _data[i], fetchState));
+                sm.store(i, toLoadable(sm, fmds[i], _data[i], fetch));
     }
 
     /**
@@ -138,7 +135,7 @@
      * into a state manager.
      */
     private static Object toLoadable(OpenJPAStateManager sm,
-        FieldMetaData fmd, Object val, FetchState fetchState) {
+        FieldMetaData fmd, Object val, FetchConfiguration fetch) {
         if (val == null)
             return null;
 
@@ -157,7 +154,7 @@
                 // it to the right type from its stored form
                 for (Iterator itr = c.iterator(); itr.hasNext();)
                     c2.add(toNestedLoadable(sm, fmd.getElement(), itr.next(),
-                        fetchState));
+                        fetch));
                 return c2;
 
             case JavaTypes.ARRAY:
@@ -175,7 +172,7 @@
                 int idx = 0;
                 for (Iterator itr = c.iterator(); itr.hasNext(); idx++)
                     Array.set(a, idx, toNestedLoadable(sm, fmd.getElement(),
-                        itr.next(), fetchState));
+                        itr.next(), fetch));
                 return a;
 
             case JavaTypes.MAP:
@@ -191,16 +188,15 @@
                 // it to the right type from its stored form
                 for (Iterator itr = m.entrySet().iterator(); itr.hasNext();) {
                     Map.Entry e = (Map.Entry) itr.next();
-                    m2.put(toNestedLoadable(sm, fmd.getKey(), e.getKey(),
-                        fetchState),
+                    m2.put(toNestedLoadable(sm, fmd.getKey(), e.getKey(),fetch),
                         toNestedLoadable(sm, fmd.getElement(), e.getValue(),
-                            fetchState));
+                            fetch));
                 }
                 return m2;
 
             default:
                 // just convert the stored value into its loadable equivalent.
-                return toNestedLoadable(sm, fmd, val, fetchState);
+                return toNestedLoadable(sm, fmd, val, fetch);
         }
     }
 
@@ -210,7 +206,7 @@
      * value; it cannot be a container.
      */
     private static Object toNestedLoadable(OpenJPAStateManager sm,
-        ValueMetaData vmd, Object val, FetchState fetchState) {
+        ValueMetaData vmd, Object val, FetchConfiguration fetch) {
         if (val == null)
             return null;
 
@@ -224,7 +220,7 @@
                 // for relations to other persistent objects, we store the related
                 // object's oid -- convert it back into a persistent instance
                 StoreContext ctx = sm.getContext();
-                Object pc = ctx.find(val, fetchState, null, null, 0);
+                Object pc = ctx.find(val, fetch, null, null, 0);
                 if (pc != null)
                     return pc;
                 OrphanedKeyAction action = ctx.getConfiguration().

Modified: incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java (original)
+++ incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/XMLStoreManager.java Fri Jul 28 16:48:13 2006
@@ -25,7 +25,6 @@
 import org.apache.openjpa.abstractstore.AbstractStoreManager;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.FetchState;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.kernel.PCState;
 import org.apache.openjpa.lib.rop.ListResultObjectProvider;
@@ -94,7 +93,7 @@
     }
 
     public boolean initialize(OpenJPAStateManager sm, PCState state,
-        FetchState fetchState, Object context) {
+        FetchConfiguration fetch, Object context) {
         // we may already have looked up the backing ObjectData (see our extent
         // implementation below), and passed it through as the context; if
         // not, then look it up in the store
@@ -115,12 +114,12 @@
         // load the data from the ObjectData into the state mgr; note that
         // this store manager doesn't do any locking -- it relies on the
         // system's lock manager to lock after the load is complete
-        data.load(sm, fetchState);
+        data.load(sm, fetch);
         return true;
     }
 
     public boolean load(OpenJPAStateManager sm, BitSet fields,
-        FetchState fetchState, int lockLevel, Object context) {
+        FetchConfiguration fetch, int lockLevel, Object context) {
         // we may already have looked up the backing ObjectData (see our extent
         // implementation below), and passed it through as the context; if
         // not, then look it up in the store
@@ -137,7 +136,7 @@
         // load the data from the ObjectData into the state mgr; note that
         // this store manager doesn't do any locking -- it relies on the
         // system's lock manager to lock after the load is complete
-        data.load(sm, fields, fetchState);
+        data.load(sm, fields, fetch);
         return true;
     }
 
@@ -278,8 +277,7 @@
             // being passed through and save ourselves a trip to the store
             // if it is present; this is particularly important in systems
             // where a trip to the store can be expensive.
-            pcs.add(ctx.find(datas[i].getId(), fetch.newFetchState(),
-                null, datas[i], 0));
+            pcs.add(ctx.find(datas[i].getId(), fetch, null, datas[i], 0));
         }
         return new ListResultObjectProvider(pcs);
     }