001: /*
002: * Copyright 2007 The Kuali Foundation
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.rice.ojb;
017:
018: import java.util.Collection;
019:
020: import org.apache.ojb.broker.PBKey;
021: import org.apache.ojb.broker.PersistenceBrokerException;
022: import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
023: import org.apache.ojb.broker.query.Query;
024: import org.kuali.rice.util.ClassLoaderUtils;
025: import org.kuali.rice.util.ContextClassLoaderBinder;
026:
027: /**
028: * Sets up the context classloader properly for OJB proxies. The sequence of events in the super class is as
029: * follows:
030: *
031: * <pre>
032: * public synchronized Collection getData()
033: * {
034: * if (!isLoaded())
035: * {
036: * beforeLoading();
037: * setData(loadData());
038: * afterLoading();
039: * }
040: * return _data;
041: * }
042: * </pre>
043: *
044: * Therefore, since there is no try-catch-finally in conjunction with this call, we need to handle exceptions thrown
045: * from loadData and unbind the classloader appropriately.
046: */
047: public class ContextClassLoaderCollectionProxy extends
048: CollectionProxyDefaultImpl {
049:
050: private static final long serialVersionUID = 6425238292133556808L;
051:
052: // this object is used by object that's are serialized and we don't want to take this reference
053: // across the wire. May need to acquire the CCL if this is null on beforeLoading() doing nothing for now...
054: private transient ClassLoader contextClassLoader;
055:
056: public ContextClassLoaderCollectionProxy(PBKey aKey,
057: Class aCollClass, Query aQuery) {
058: super (aKey, aCollClass, aQuery);
059: this .contextClassLoader = ClassLoaderUtils
060: .getDefaultClassLoader();
061: }
062:
063: public ContextClassLoaderCollectionProxy(PBKey aKey, Query aQuery) {
064: super (aKey, aQuery);
065: this .contextClassLoader = ClassLoaderUtils
066: .getDefaultClassLoader();
067: }
068:
069: @Override
070: protected void beforeLoading() {
071: ContextClassLoaderBinder.bind(this .contextClassLoader);
072: super .beforeLoading();
073: }
074:
075: @Override
076: protected Collection loadData() throws PersistenceBrokerException {
077: try {
078: return super .loadData();
079: } catch (Throwable t) {
080: ContextClassLoaderBinder.unbind();
081: if (t instanceof PersistenceBrokerException) {
082: throw (PersistenceBrokerException) t;
083: } else if (t instanceof Error) {
084: throw (Error) t;
085: } else if (t instanceof RuntimeException) {
086: throw (RuntimeException) t;
087: } else {
088: throw new PersistenceBrokerException(
089: "Invalid exception type thrown!", t);
090: }
091: }
092: }
093:
094: @Override
095: protected void afterLoading() {
096: super.afterLoading();
097: ContextClassLoaderBinder.unbind();
098: }
099:
100: }
|