View Javadoc

1   /*
2    * Copyright 2007-2008 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.core.ojb;
17  
18  import java.util.Collection;
19  
20  import org.apache.ojb.broker.PBKey;
21  import org.apache.ojb.broker.PersistenceBrokerException;
22  import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
23  import org.apache.ojb.broker.query.Query;
24  import org.kuali.rice.core.util.ClassLoaderUtils;
25  import org.kuali.rice.core.util.ContextClassLoaderBinder;
26  
27  /**
28   * Sets up the context classloader properly for OJB proxies.  The sequence of events in the super class is as
29   * follows:
30   * 
31   * <pre>
32   * public synchronized Collection getData()
33   * {
34   *    if (!isLoaded())
35   *    {
36   *      beforeLoading();
37   *      setData(loadData());
38   *      afterLoading();
39   *    }
40   *    return _data;
41   * }
42   * </pre>
43   *
44   * Therefore, since there is no try-catch-finally in conjunction with this call, we need to handle exceptions thrown
45   * from loadData and unbind the classloader appropriately.
46   */
47  public class ContextClassLoaderCollectionProxy extends CollectionProxyDefaultImpl {
48  
49  	private static final long serialVersionUID = 6425238292133556808L;
50  
51  	// this object is used by object that's are serialized and we don't want to take this reference
52  	// across the wire.  May need to acquire the CCL if this is null on beforeLoading() doing nothing for now...
53  	private transient ClassLoader contextClassLoader;
54  	
55  	public ContextClassLoaderCollectionProxy(PBKey aKey, Class aCollClass, Query aQuery) {
56  		super(aKey, aCollClass, aQuery);
57  		this.contextClassLoader = ClassLoaderUtils.getDefaultClassLoader();
58  	}
59  
60  	public ContextClassLoaderCollectionProxy(PBKey aKey, Query aQuery) {
61  		super(aKey, aQuery);
62  		this.contextClassLoader = ClassLoaderUtils.getDefaultClassLoader();	
63  	}
64  
65  	@Override
66  	protected void beforeLoading() {
67  		ContextClassLoaderBinder.bind(this.contextClassLoader);
68  		super.beforeLoading();
69  	}
70  	
71  	@Override
72  	protected Collection loadData() throws PersistenceBrokerException {
73  		try {
74  			return super.loadData();
75  		} catch (Throwable t) {
76  			ContextClassLoaderBinder.unbind();
77  			if (t instanceof PersistenceBrokerException) {
78  				throw (PersistenceBrokerException)t;
79  			} else if (t instanceof Error) {
80  				throw (Error)t;
81  			} else if (t instanceof RuntimeException) {
82  				throw (RuntimeException)t;
83  			} else {
84  				throw new PersistenceBrokerException("Invalid exception type thrown!", t);
85  			}
86  		}
87  	}
88  
89  	@Override
90  	protected void afterLoading() {
91  		super.afterLoading();
92  		ContextClassLoaderBinder.unbind();
93  	}
94  	
95  }