001: package org.apache.ojb.broker.metadata.fieldaccess;
002:
003: /* Copyright 2002-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import java.io.Serializable;
019:
020: import org.apache.ojb.broker.metadata.MetadataException;
021: import org.apache.ojb.broker.util.ClassHelper;
022:
023: /**
024: * PeristentField implementation that attempts to detect the nature of
025: * the field it is persisting.
026: * <p>
027: * First checks to see if it is a Field, then Property, then DynaBean
028: * <p>
029: * It will match in that order.
030: */
031: public class PersistentFieldAutoProxyImpl extends PersistentFieldBase {
032: static final long serialVersionUID = 6286229945422476325L;
033:
034: /**
035: * Define the number and ordering of the used {@link PersistentField}
036: * implementaions. Override this field to add new classes or to change
037: * setection order.
038: */
039: protected Class[] persistentFieldClasses = new Class[] {
040: PersistentFieldDirectImpl.class,
041: PersistentFieldIntrospectorImpl.class,
042: PersistentFieldPrivilegedImpl.class,
043: PersistentFieldDynaBeanImpl.class };
044:
045: private PersistentField currentPF;
046: private ExceptionWrapper latestException;
047: int index = 0;
048:
049: public PersistentFieldAutoProxyImpl() {
050: }
051:
052: public PersistentFieldAutoProxyImpl(Class clazz, String fieldname) {
053: super (clazz, fieldname);
054: }
055:
056: private PersistentField getCurrent() {
057: if (currentPF == null) {
058: if (index >= persistentFieldClasses.length) {
059: index = 0;
060: currentPF = null;
061: throw new AutoDetectException(
062: "Can't autodetect valid PersistentField implementation: "
063: + latestException.message,
064: latestException.exception);
065: }
066: try {
067: currentPF = createPersistentFieldForIndex();
068: } catch (Exception e) {
069: throw new AutoDetectException(
070: "Can't create instance for "
071: + persistentFieldClasses[index], e);
072: }
073: }
074: return currentPF;
075: }
076:
077: private void handleException(String message, Exception e) {
078: latestException = new ExceptionWrapper(message, e);
079: currentPF = null;
080: ++index;
081: }
082:
083: public Object get(Object anObject) throws MetadataException {
084: try {
085: return getCurrent().get(anObject);
086: } catch (Exception e) {
087: if (e instanceof AutoDetectException) {
088: throw (MetadataException) e;
089: } else {
090: handleException("Can't extract field value for field "
091: + getName()
092: + " from object "
093: + (anObject != null ? anObject.getClass()
094: : null), e);
095: return get(anObject);
096: }
097: }
098: }
099:
100: public void set(Object obj, Object value) throws MetadataException {
101: try {
102: getCurrent().set(obj, value);
103: } catch (Exception e) {
104: if (e instanceof AutoDetectException) {
105: throw (MetadataException) e;
106: } else {
107: handleException("Can't set value for field "
108: + getName() + " to object "
109: + (obj != null ? obj.getClass() : null), e);
110: set(obj, value);
111: }
112: }
113: }
114:
115: public Class getType() {
116: try {
117: return getCurrent().getType();
118: } catch (Exception e) {
119: if (e instanceof AutoDetectException) {
120: throw (MetadataException) e;
121: } else {
122: handleException("Can't identify field type for field "
123: + getName(), null);
124: return getType();
125: }
126: }
127: }
128:
129: protected boolean makeAccessible() {
130: return false;
131: }
132:
133: public boolean usesAccessorsAndMutators() {
134: return false;
135: }
136:
137: private PersistentField createPersistentFieldForIndex()
138: throws Exception {
139: return newInstance(persistentFieldClasses[index]);
140: }
141:
142: private PersistentField newInstance(Class pfClass) throws Exception {
143: Class[] types = new Class[] { Class.class, String.class };
144: Object[] args = new Object[] { getDeclaringClass(), getName() };
145: return (PersistentField) ClassHelper.newInstance(pfClass,
146: types, args);
147: }
148:
149: static class ExceptionWrapper implements Serializable {
150: private static final long serialVersionUID = 3691042088451912249L;
151: Exception exception;
152: String message;
153:
154: public ExceptionWrapper(String message, Exception exception) {
155: this .message = message;
156: this .exception = exception;
157: }
158: }
159:
160: static class AutoDetectException extends MetadataException {
161: private static final long serialVersionUID = 3257290223049585970L;
162:
163: public AutoDetectException() {
164: super ();
165: }
166:
167: public AutoDetectException(Throwable t) {
168: super (t);
169: }
170:
171: public AutoDetectException(String message) {
172: super (message);
173: }
174:
175: public AutoDetectException(String message, Throwable t) {
176: super(message, t);
177: }
178: }
179: }
|