001: /**********************************************************************
002: Copyright (c) 2007 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: Contributors:
016: ...
017: **********************************************************************/package org.jpox.store.fieldmanager;
018:
019: import java.util.Collection;
020: import java.util.Iterator;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import org.jpox.StateManager;
025: import org.jpox.api.ApiAdapter;
026: import org.jpox.metadata.AbstractMemberMetaData;
027: import org.jpox.util.JPOXLogger;
028: import org.jpox.util.Localiser;
029:
030: /**
031: * Field manager that runs reachability on all PC objects referenced from the source object.
032: * Whenever a PC object is encountered "runReachability" is performed on the StateManager of the object.
033: *
034: * @version $Revision: 1.4 $
035: */
036: public class ReachabilityFieldManager extends AbstractFieldManager {
037: /** Localiser for messages. */
038: protected static final Localiser LOCALISER = Localiser
039: .getInstance("org.jpox.Localisation");
040:
041: /** StateManager for the owning object. */
042: private final StateManager sm;
043:
044: /** Set of reachables up to this point. */
045: private Set reachables = null;
046:
047: /**
048: * Constructor.
049: * @param sm The state manager for the object.
050: * @param reachables Reachables up to this point
051: */
052: public ReachabilityFieldManager(StateManager sm, Set reachables) {
053: this .sm = sm;
054: this .reachables = reachables;
055: }
056:
057: /**
058: * Utility method to process the passed persistable object.
059: * @param obj The persistable object
060: * @param fmd MetaData for the field storing this object
061: */
062: protected void processPersistable(Object obj,
063: AbstractMemberMetaData fmd) {
064: // TODO Remove this reference to PersistenceCabable
065: ApiAdapter api = sm.getObjectManager().getApiAdapter();
066: org.jpox.StateManager sm = this .sm.getObjectManager()
067: .findStateManager(obj);
068: if (sm != null) {
069: sm.runReachability(reachables);
070: } else {
071: if (JPOXLogger.REACHABILITY.isDebugEnabled()) {
072: JPOXLogger.REACHABILITY.debug(LOCALISER
073: .msg("007005", api.getIdForObject(obj), fmd
074: .getFullFieldName()));
075: }
076: }
077: }
078:
079: /**
080: * Method to store an object field.
081: * @param fieldNumber Number of the field (absolute)
082: * @param value Value of the field
083: */
084: public void storeObjectField(int fieldNumber, Object value) {
085: AbstractMemberMetaData fmd = sm.getClassMetaData()
086: .getMetaDataForManagedMemberAtAbsolutePosition(
087: fieldNumber);
088: if (value != null) {
089: boolean persistCascade = fmd.isCascadePersist();
090: ApiAdapter api = sm.getObjectManager().getApiAdapter();
091: if (persistCascade) {
092: if (api.isPersistable(value)) {
093: // Process PC fields
094: if (JPOXLogger.REACHABILITY.isDebugEnabled()) {
095: JPOXLogger.REACHABILITY.debug(LOCALISER.msg(
096: "007004", fmd.getFullFieldName()));
097: }
098: processPersistable(value, fmd);
099: } else if (value instanceof Collection) {
100: // Process all elements of the Collection that are PC
101: if (JPOXLogger.REACHABILITY.isDebugEnabled()) {
102: JPOXLogger.REACHABILITY.debug(LOCALISER.msg(
103: "007002", fmd.getFullFieldName()));
104: }
105: Collection coll = (Collection) value;
106: Iterator iter = coll.iterator();
107: while (iter.hasNext()) {
108: Object element = iter.next();
109: if (api.isPersistable(element)) {
110: processPersistable(element, fmd);
111: }
112: }
113: } else if (value instanceof Map) {
114: // Process all keys, values of the Map that are PC
115: Map map = (Map) value;
116:
117: // Process any keys that are PersistenceCapable
118: if (JPOXLogger.REACHABILITY.isDebugEnabled()) {
119: JPOXLogger.REACHABILITY.debug(LOCALISER.msg(
120: "007002", fmd.getFullFieldName()));
121: }
122: Set keys = map.keySet();
123: Iterator iter = keys.iterator();
124: while (iter.hasNext()) {
125: Object mapKey = iter.next();
126: if (api.isPersistable(mapKey)) {
127: processPersistable(mapKey, fmd);
128: }
129: }
130:
131: // Process any values that are PersistenceCapable
132: Collection values = map.values();
133: iter = values.iterator();
134: while (iter.hasNext()) {
135: Object mapValue = iter.next();
136: if (api.isPersistable(mapValue)) {
137: processPersistable(mapValue, fmd);
138: }
139: }
140: } else if (value instanceof Object[]) {
141: // Process all array elements that are PC
142: if (JPOXLogger.REACHABILITY.isDebugEnabled()) {
143: JPOXLogger.REACHABILITY.debug(LOCALISER.msg(
144: "007003", fmd.getFullFieldName()));
145: }
146: Object[] array = (Object[]) value;
147: for (int i = 0; i < array.length; i++) {
148: Object element = array[i];
149: if (api.isPersistable(element)) {
150: processPersistable(element, fmd);
151: }
152: }
153: } else {
154: // Primitive, or primitive array, or some unsupported container type
155: }
156: }
157: } else {
158: if (JPOXLogger.REACHABILITY.isDebugEnabled()) {
159: JPOXLogger.REACHABILITY.debug(LOCALISER.msg("007001",
160: fmd.getFullFieldName()));
161: }
162: }
163: }
164:
165: /**
166: * Method to store a boolean field.
167: * @param fieldNumber Number of the field (absolute)
168: * @param value Value of the field
169: */
170: public void storeBooleanField(int fieldNumber, boolean value) {
171: // Do nothing
172: }
173:
174: /**
175: * Method to store a byte field.
176: * @param fieldNumber Number of the field (absolute)
177: * @param value Value of the field
178: */
179: public void storeByteField(int fieldNumber, byte value) {
180: // Do nothing
181: }
182:
183: /**
184: * Method to store a char field.
185: * @param fieldNumber Number of the field (absolute)
186: * @param value Value of the field
187: */
188: public void storeCharField(int fieldNumber, char value) {
189: // Do nothing
190: }
191:
192: /**
193: * Method to store a double field.
194: * @param fieldNumber Number of the field (absolute)
195: * @param value Value of the field
196: */
197: public void storeDoubleField(int fieldNumber, double value) {
198: // Do nothing
199: }
200:
201: /**
202: * Method to store a float field.
203: * @param fieldNumber Number of the field (absolute)
204: * @param value Value of the field
205: */
206: public void storeFloatField(int fieldNumber, float value) {
207: // Do nothing
208: }
209:
210: /**
211: * Method to store an int field.
212: * @param fieldNumber Number of the field (absolute)
213: * @param value Value of the field
214: */
215: public void storeIntField(int fieldNumber, int value) {
216: // Do nothing
217: }
218:
219: /**
220: * Method to store a long field.
221: * @param fieldNumber Number of the field (absolute)
222: * @param value Value of the field
223: */
224: public void storeLongField(int fieldNumber, long value) {
225: // Do nothing
226: }
227:
228: /**
229: * Method to store a short field.
230: * @param fieldNumber Number of the field (absolute)
231: * @param value Value of the field
232: */
233: public void storeShortField(int fieldNumber, short value) {
234: // Do nothing
235: }
236:
237: /**
238: * Method to store a string field.
239: * @param fieldNumber Number of the field (absolute)
240: * @param value Value of the field
241: */
242: public void storeStringField(int fieldNumber, String value) {
243: // Do nothing
244: }
245: }
|