mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-08-13 16:53:55 -04:00
197 lines
6.5 KiB
Java
197 lines
6.5 KiB
Java
|
/*
|
||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||
|
* contributor license agreements. See the NOTICE file distributed with
|
||
|
* this work for additional information regarding copyright ownership.
|
||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||
|
* (the "License"); you may not use this file except in compliance with
|
||
|
* the License. You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* $Header:$
|
||
|
*/
|
||
|
package org.apache.beehive.controls.system.ejb;
|
||
|
|
||
|
import java.io.Serializable;
|
||
|
import java.lang.reflect.InvocationTargetException;
|
||
|
import java.lang.reflect.Method;
|
||
|
import java.rmi.RemoteException;
|
||
|
import java.util.Collection;
|
||
|
import java.util.Iterator;
|
||
|
import javax.ejb.EJBLocalObject;
|
||
|
import javax.ejb.EJBObject;
|
||
|
|
||
|
import org.apache.beehive.controls.api.ControlException;
|
||
|
import org.apache.beehive.controls.api.bean.ControlImplementation;
|
||
|
|
||
|
/**
|
||
|
* The EntityEJBControlImpl class is the control implementation class for
|
||
|
* Entity EJBs.
|
||
|
*/
|
||
|
@ControlImplementation(assembler = EJBControlAssembler.class)
|
||
|
public class EntityEJBControlImpl
|
||
|
extends EJBControlImpl
|
||
|
implements EntityEJBControl, java.io.Serializable {
|
||
|
|
||
|
static final long serialVersionUID = 1L;
|
||
|
|
||
|
//
|
||
|
// Implements auto-find semantics for entity beans
|
||
|
//
|
||
|
protected Object resolveBeanInstance() {
|
||
|
// Already resolved and cached
|
||
|
if (_beanInstance != null)
|
||
|
return _beanInstance;
|
||
|
|
||
|
// Attempt to resolve from a cached handle
|
||
|
_beanInstance = resolveBeanInstanceFromHandle();
|
||
|
if (_beanInstance != null)
|
||
|
return _beanInstance;
|
||
|
|
||
|
// Attempt to resolve bean instance from cached primary key
|
||
|
if (_lastKey == null)
|
||
|
throw new ControlException("Unable to locate a target bean instance, because a successful create or finder method has not been executed.");
|
||
|
|
||
|
Class [] findArgType = new Class[]{_lastKey.getClass()};
|
||
|
try {
|
||
|
Method finder = _homeInterface.getMethod("findByPrimaryKey", findArgType);
|
||
|
return finder.invoke(_homeInstance, new Object []{_lastKey});
|
||
|
}
|
||
|
catch (NoSuchMethodException nsme) {
|
||
|
throw new ControlException("Unable to locate findByPrimaryKey method on home interface", nsme);
|
||
|
}
|
||
|
catch (InvocationTargetException ite) {
|
||
|
_lastException = ite.getTargetException();
|
||
|
throw new ControlException("Failure to locate entity instance associated with the last primary key", _lastException);
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
throw new ControlException("Unexpected exception in auto-find", e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected boolean saveBeanInstance() {
|
||
|
//
|
||
|
// First, delegate to parent (handle-based persistence)
|
||
|
//
|
||
|
if (super.saveBeanInstance())
|
||
|
return true;
|
||
|
|
||
|
//
|
||
|
// Fall back to persistence using a saved primary key value
|
||
|
//
|
||
|
try {
|
||
|
if (_beanInstance instanceof EJBObject)
|
||
|
_lastKey = (Serializable) ((EJBObject) _beanInstance).getPrimaryKey();
|
||
|
else
|
||
|
_lastKey = (Serializable) ((EJBLocalObject) _beanInstance).getPrimaryKey();
|
||
|
}
|
||
|
catch (RemoteException re) {
|
||
|
throw new ControlException("Unable to save bean instance", re);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Release the bean instance. Entity bean instances are *never* removed, except via
|
||
|
// direct client calls to the remove method.
|
||
|
//
|
||
|
protected void releaseBeanInstance(boolean alreadyRemoved) {
|
||
|
super.releaseBeanInstance(alreadyRemoved);
|
||
|
|
||
|
// Release any cached primary key value
|
||
|
_lastKey = null;
|
||
|
}
|
||
|
|
||
|
private boolean isMultiSelectorMethod(Method m) {
|
||
|
return isFinderMethod(m) && m.getReturnType().isAssignableFrom(Collection.class);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This method wraps the base EJBControlImpl invoke, doing the additional
|
||
|
// work to maintain the primary key cache for methods which alter the
|
||
|
// target bean instance.
|
||
|
//
|
||
|
public Object invoke(Method m, Object [] args) throws Throwable {
|
||
|
Throwable invokeException = null;
|
||
|
Object retval = null;
|
||
|
Object currentBeanInstance = _beanInstance;
|
||
|
try {
|
||
|
retval = super.invoke(m, args);
|
||
|
}
|
||
|
catch (Exception t) {
|
||
|
// a tasty treat, but I'll throw up later
|
||
|
invokeException = t;
|
||
|
}
|
||
|
|
||
|
if (isControlBeanMethod(m)) {
|
||
|
m = mapControlBeanMethodToEJB(m);
|
||
|
}
|
||
|
|
||
|
if (isMultiSelectorMethod(m)) {
|
||
|
releaseBeanInstance(false);
|
||
|
|
||
|
Collection collection = (Collection) retval;
|
||
|
if (collection != null && !collection.isEmpty()) {
|
||
|
_colIter = collection.iterator();
|
||
|
_beanInstance = beanNarrow(_colIter.next());
|
||
|
}
|
||
|
else releaseBeanInstance(false);
|
||
|
}
|
||
|
else if (isSelectorMethod(m)) {
|
||
|
// Release collection results if a single select method is called.
|
||
|
_colIter = null;
|
||
|
}
|
||
|
|
||
|
if (invokeException != null)
|
||
|
throw invokeException;
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* EntityEJBControl.getEJBNextBeanInstance()
|
||
|
*/
|
||
|
public Object getEJBNextBeanInstance() {
|
||
|
if (_colIter == null)
|
||
|
return null;
|
||
|
|
||
|
if (!_colIter.hasNext()) {
|
||
|
releaseBeanInstance(false);
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
_beanInstance = beanNarrow(_colIter.next());
|
||
|
return _beanInstance;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Override the onCreate event handler that was already defined in EJBControlImpl to
|
||
|
// add additional processing.
|
||
|
//
|
||
|
public void onCreate() {
|
||
|
super.onCreate();
|
||
|
if (_beanType != EJBControlImpl.ENTITY_BEAN) {
|
||
|
throw new ControlException("Attempting to use a entity bean control with a bean that is not a entity bean");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Override the onReset event handler that was already defined in EJBControlImpl to
|
||
|
// add additional processing.
|
||
|
//
|
||
|
public void onReset() {
|
||
|
super.onReset();
|
||
|
_lastKey = null;
|
||
|
_colIter = null;
|
||
|
}
|
||
|
|
||
|
private Serializable _lastKey; // primary key of the selected instance
|
||
|
private transient Iterator _colIter; // multi-finder result iterator
|
||
|
}
|