001: /**********************************************************************
002: Copyright (c) 2006 Andy Jefferson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: ...
018: **********************************************************************/package org.jpox.store.fieldmanager;
019:
020: import java.util.Collection;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.Set;
024:
025: import org.jpox.ObjectManager;
026: import org.jpox.ObjectManagerHelper;
027: import org.jpox.StateManager;
028: import org.jpox.FetchPlan.FetchPlanForClass;
029: import org.jpox.api.ApiAdapter;
030: import org.jpox.sco.SCO;
031: import org.jpox.state.FetchPlanState;
032:
033: /**
034: * Field Manager to handle loading all fields of all objects in the fetch plan.
035: * The method in StateManagerImpl only loads the fields for that object and so
036: * will only load the DFG fields for objects (hence omitting any non-DFG fields
037: * that are in the FetchPlan that have been omitted due to lazy-loading).
038: *
039: * @version $Revision: 1.7 $
040: **/
041: public class LoadFieldManager extends AbstractFetchFieldManager {
042: /**
043: * Constructor for a field manager for make transient process.
044: * @param sm the StateManager of the instance being loaded
045: * @param secondClassMutableFields The second class mutable fields for the class of this object
046: * @param fpClass Fetch Plan for the class of this instance
047: * @param state State object to hold any pertinent controls for the fetchplan process
048: */
049: public LoadFieldManager(StateManager sm,
050: boolean[] secondClassMutableFields,
051: FetchPlanForClass fpClass, FetchPlanState state) {
052: super (sm, secondClassMutableFields, fpClass, state);
053: }
054:
055: /**
056: * Utility method to process the passed persistable object.
057: * @param pc The PC object
058: */
059: protected void processPersistable(Object pc) {
060: ObjectManager om = ObjectManagerHelper.getObjectManager(pc);
061: if (om != null) {
062: // Field is persisted (otherwise it may have not been persisted by reachability)
063: om.findStateManager(pc).loadFieldsInFetchPlan(state);
064: }
065: }
066:
067: /**
068: * Method to fetch an object field whether it is SCO collection, PC, or whatever for the fetchplan process.
069: * @param fieldNumber Number of the field
070: * @return The object
071: */
072: protected Object internalFetchObjectField(int fieldNumber) {
073: SingleValueFieldManager sfv = new SingleValueFieldManager();
074: sm.provideFields(new int[] { fieldNumber }, sfv);
075: Object value = sfv.fetchObjectField(fieldNumber);
076: ApiAdapter api = sm.getObjectManager().getApiAdapter();
077:
078: if (value != null) {
079: if (api.isPersistable(value)) {
080: // Process PC fields
081: processPersistable(value);
082: } else if (value instanceof Collection) {
083: // Process all elements of the Collection that are PC
084: if (!(value instanceof SCO)) {
085: // Replace with SCO
086: value = sm.wrapSCOField(fieldNumber, value, false,
087: false, true);
088: }
089:
090: Collection coll = (Collection) value;
091: Iterator iter = coll.iterator();
092: while (iter.hasNext()) {
093: Object element = iter.next();
094: if (api.isPersistable(element)) {
095: processPersistable(element);
096: }
097: }
098: } else if (value instanceof Map) {
099: // Process all keys, values of the Map that are PC
100: if (!(value instanceof SCO)) {
101: // Replace with SCO
102: value = sm.wrapSCOField(fieldNumber, value, false,
103: false, true);
104: }
105:
106: Map map = (Map) value;
107:
108: // Process any keys that are PersistenceCapable
109: Set keys = map.keySet();
110: Iterator iter = keys.iterator();
111: while (iter.hasNext()) {
112: Object mapKey = iter.next();
113: if (api.isPersistable(mapKey)) {
114: processPersistable(mapKey);
115: }
116: }
117:
118: // Process any values that are PersistenceCapable
119: Collection values = map.values();
120: iter = values.iterator();
121: while (iter.hasNext()) {
122: Object mapValue = iter.next();
123: if (api.isPersistable(mapValue)) {
124: processPersistable(mapValue);
125: }
126: }
127: } else if (value instanceof Object[]) {
128: Object[] array = (Object[]) value;
129: for (int i = 0; i < array.length; i++) {
130: Object element = array[i];
131: if (api.isPersistable(element)) {
132: processPersistable(element);
133: }
134: }
135: }
136: }
137:
138: return value;
139: }
140:
141: /**
142: * Method called when were arrive at the end of a branch
143: * @param fieldNumber Number of the field
144: * @return Object to return
145: */
146: protected Object endOfGraphOperation(int fieldNumber) {
147: SingleValueFieldManager sfv = new SingleValueFieldManager();
148: sm.provideFields(new int[] { fieldNumber }, sfv);
149: Object value = sfv.fetchObjectField(fieldNumber);
150:
151: return value;
152: }
153: }
|