blob: e0a697acfcc96d22ddcf047a88e5ccbefa4b8684 [file] [log] [blame]
/*
* 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.
*/
package org.apache.openjpa.event;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.UserException;
/**
* Performs a callback method on a cached bean instance.
*
* @author Steve Kim
*/
public class BeanLifecycleCallbacks
extends MethodLifecycleCallbacks {
private static final Localizer _loc = Localizer.forPackage
(BeanLifecycleCallbacks.class);
private transient Object _listener;
/**
* Constructor. Make the callback on an instance of the given type.
*
* @param arg whether another argument is expected such as AfterDetach
*/
public BeanLifecycleCallbacks(Class<?> cls, String method, boolean arg,
Class<?> type) {
this(cls, getMethod(cls, method, arg ? new Class[]{ Object.class,
type } : new Class[]{ type }), arg);
}
/**
* Constructor. Make the callback on an instance of the given type.
*/
public BeanLifecycleCallbacks(Class<?> cls, Method method, boolean arg) {
super(method, arg);
_listener = newListener(cls);
}
private Object newListener(Class<?> cls) {
try {
return AccessController.doPrivileged(
J2DoPrivHelper.newInstanceAction(cls));
} catch (Throwable t) {
if (t instanceof PrivilegedActionException)
t = ((PrivilegedActionException) t).getException();
throw new UserException(_loc.get("bean-constructor",
cls.getName()), t);
}
}
@Override
public void makeCallback(Object obj, Object rel, int eventType)
throws Exception {
Method callback = getCallbackMethod();
if (!callback.isAccessible())
AccessController.doPrivileged(J2DoPrivHelper.setAccessibleAction(
callback, true));
if (requiresArgument())
callback.invoke(_listener, new Object[]{ obj, rel });
else
callback.invoke(_listener, new Object[]{ obj });
}
@Override
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
super.readExternal(in);
Class<?> cls = (Class<?>) in.readObject();
_listener = newListener(cls);
}
@Override
public void writeExternal(ObjectOutput out)
throws IOException {
super.writeExternal(out);
out.writeObject(_listener.getClass());
}
}