下面列出了怎么用javax.ejb.EJBLocalObject的API类实例代码及写法,或者点击链接到github查看源代码。
private void mapObjectInterface(final Class intrface) {
if (intrface == BusinessLocalHome.class || intrface == BusinessRemoteHome.class || intrface == ServiceEndpoint.class) {
return;
}
final Method[] interfaceMethods = intrface.getMethods();
for (final Method method : interfaceMethods) {
final Class declaringClass = method.getDeclaringClass();
if (declaringClass == EJBObject.class || declaringClass == EJBLocalObject.class) {
continue;
}
try {
final Method beanMethod = beanClass.getMethod(method.getName(), method.getParameterTypes());
mapMethods(method, beanMethod);
} catch (final NoSuchMethodException nsme) {
throw new OpenEJBRuntimeException("Invalid method [" + method + "]. Not declared by " + beanClass.getName() + " class");
}
}
}
public EJBLocalObject getEJBLocalObject() throws IllegalStateException {
doCheck(Call.getEJBLocalObject);
final ThreadContext threadContext = ThreadContext.getThreadContext();
final BeanContext di = threadContext.getBeanContext();
if (di.getLocalInterface() == null) {
throw new IllegalStateException("EJB " + di.getDeploymentID() + " does not have a local interface");
}
final EjbObjectProxyHandler handler = new EntityEjbObjectHandler(di, threadContext.getPrimaryKey(), InterfaceType.EJB_LOCAL, new ArrayList<>(), di.getLocalInterface());
try {
final Class[] interfaces = new Class[]{di.getLocalInterface(), IntraVmProxy.class};
return (EJBLocalObject) ProxyManager.newProxyInstance(interfaces, handler);
} catch (final IllegalAccessException iae) {
throw new InternalErrorException("Could not create IVM proxy for " + di.getLocalInterface() + " interface", iae);
}
}
public static <Proxy extends EJBLocalObject> Proxy getEjbProxy(final BeanContext beanContext, final EntityBean entity) {
if (entity == null) {
return null;
}
// build the primary key
final Object primaryKey = getPrimaryKey(beanContext, entity);
// get the cmp container
if (!(beanContext.getContainer() instanceof CmpContainer)) {
throw new IllegalArgumentException("Proxy is not connected to a CMP container but is conect to " + beanContext.getContainer().getClass().getName());
}
final Proxy proxy = (Proxy) EjbObjectProxyHandler.createProxy(beanContext, primaryKey, InterfaceType.EJB_LOCAL_HOME, beanContext.getLocalInterface());
return proxy;
}
private static <Bean extends EntityBean> Set<Bean> getEntityBeans(final Collection<?> proxies, final Class type) {
if (proxies == null) {
return null;
}
final Set<Bean> entities = new HashSet<>();
for (final Object value : proxies) {
if (type != null && !type.isInstance(value)) {
throw new IllegalArgumentException("Object is not an instance of " + type.getName() +
": " + (value == null ? "null" : value.getClass().getName()));
}
final Bean entity = Cmp2Util.<Bean>getEntityBean((EJBLocalObject) value);
if (entity == null) {
throw new IllegalArgumentException("Entity has been deleted");
}
entities.add(entity);
}
return entities;
}
/**
* Remove the given EJB instance.
* @param ejb the EJB instance to remove
* @see javax.ejb.EJBLocalObject#remove()
*/
protected void removeSessionBeanInstance(@Nullable EJBLocalObject ejb) {
if (ejb != null && !this.homeAsComponent) {
try {
ejb.remove();
}
catch (Throwable ex) {
logger.warn("Could not invoke 'remove' on local EJB proxy", ex);
}
}
}
/**
* Remove the given EJB instance.
* @param ejb the EJB instance to remove
* @see javax.ejb.EJBLocalObject#remove()
*/
protected void removeSessionBeanInstance(@Nullable EJBLocalObject ejb) {
if (ejb != null && !this.homeAsComponent) {
try {
ejb.remove();
}
catch (Throwable ex) {
logger.warn("Could not invoke 'remove' on local EJB proxy", ex);
}
}
}
/**
* Remove the given EJB instance.
* @param ejb the EJB instance to remove
* @see javax.ejb.EJBLocalObject#remove()
*/
protected void removeSessionBeanInstance(EJBLocalObject ejb) {
if (ejb != null && !this.homeAsComponent) {
try {
ejb.remove();
}
catch (Throwable ex) {
logger.warn("Could not invoke 'remove' on local EJB proxy", ex);
}
}
}
/**
* Remove the given EJB instance.
* @param ejb the EJB instance to remove
* @see javax.ejb.EJBLocalObject#remove()
*/
protected void removeSessionBeanInstance(EJBLocalObject ejb) {
if (ejb != null && !this.homeAsComponent) {
try {
ejb.remove();
}
catch (Throwable ex) {
logger.warn("Could not invoke 'remove' on local EJB proxy", ex);
}
}
}
@ExpectWarning("BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY")
public void cascadeDelete(Collection value) throws RemoveException
{
if(!value.isEmpty())
{
EJBLocalObject[] locals = (EJBLocalObject[])value.toArray();
for(int i = 0; i < locals.length; ++i)
{
locals[i].remove();
}
}
}
public InterfaceType getInterfaceType(final Class clazz) {
final InterfaceType type = interfaces.get(clazz);
if (type != null) {
return type;
}
if (EJBLocalHome.class.isAssignableFrom(clazz)) {
return InterfaceType.EJB_LOCAL_HOME;
}
if (EJBLocalObject.class.isAssignableFrom(clazz)) {
return InterfaceType.EJB_LOCAL;
}
if (EJBHome.class.isAssignableFrom(clazz)) {
return InterfaceType.EJB_HOME;
}
if (EJBObject.class.isAssignableFrom(clazz)) {
return InterfaceType.EJB_OBJECT;
}
for (final Entry<Class, InterfaceType> entry : interfaces.entrySet()) { // for @Remote case where the loaded interface can be different from the stored one
if (entry.getKey().getName().equals(clazz.getName())) {
return entry.getValue();
}
}
return null;
}
private static boolean containerMethod(final Method method) {
return (method.getDeclaringClass() == EJBObject.class ||
method.getDeclaringClass() == EJBHome.class ||
method.getDeclaringClass() == EJBLocalObject.class ||
method.getDeclaringClass() == EJBLocalHome.class) &&
!method.getName().equals("remove");
}
public EJBLocalObject getEJBLocalObject() throws IllegalStateException {
doCheck(Call.getEJBLocalObject);
final ThreadContext threadContext = ThreadContext.getThreadContext();
final BeanContext di = threadContext.getBeanContext();
if (di.getLocalHomeInterface() == null) {
throw new IllegalStateException("Bean does not have an EJBLocalObject interface: " + di.getDeploymentID());
}
return (EJBLocalObject) EjbObjectProxyHandler.createProxy(di, threadContext.getPrimaryKey(), InterfaceType.EJB_LOCAL, di.getLocalInterface());
}
private List<Object> executeSelectQuery(final Query query, Object[] args) {
// process args
if (args == null) {
args = NO_ARGS;
}
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
// ejb proxies need to be swapped out for real instance classes
if (arg instanceof EJBObject) {
arg = Cmp2Util.getEntityBean((EJBObject) arg);
}
if (arg instanceof EJBLocalObject) {
arg = Cmp2Util.getEntityBean((EJBLocalObject) arg);
}
try {
query.getParameter(i + 1);
} catch (final IllegalArgumentException e) {
// IllegalArgumentException means that the parameter with the
// specified position does not exist
continue;
}
query.setParameter(i + 1, arg);
}
// todo results should not be iterated over, but should instead
// perform all work in a wrapper list on demand by the application code
final List results = query.getResultList();
for (final Object value : results) {
if (value instanceof EntityBean) {
// todo don't activate beans already activated
final EntityBean entity = (EntityBean) value;
cmpCallback.setEntityContext(entity);
cmpCallback.ejbActivate(entity);
}
}
//noinspection unchecked
return results;
}
public int executeUpdateQuery(final BeanContext beanContext, final String signature, Object[] args) throws FinderException {
final EntityManager entityManager = getEntityManager(beanContext);
Query query = createNamedQuery(entityManager, signature);
if (query == null) {
final int parenIndex = signature.indexOf('(');
if (parenIndex > 0) {
final String shortName = signature.substring(0, parenIndex);
query = createNamedQuery(entityManager, shortName);
}
if (query == null) {
throw new FinderException("No query defined for method " + signature);
}
}
// process args
if (args == null) {
args = NO_ARGS;
}
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
// ejb proxies need to be swapped out for real instance classes
if (arg instanceof EJBObject) {
arg = Cmp2Util.getEntityBean((EJBObject) arg);
}
if (arg instanceof EJBLocalObject) {
arg = Cmp2Util.getEntityBean((EJBLocalObject) arg);
}
query.setParameter(i + 1, arg);
}
final int result = query.executeUpdate();
return result;
}
public boolean contains(final Object o) {
if (relatedLocal.isInstance(o)) {
final Bean entity = getEntityBean((EJBLocalObject) o);
return entity != null && getRelatedBeans(false, false).contains(entity);
}
return false;
}
public boolean add(final Object proxy) {
if (!relatedLocal.isInstance(proxy)) {
throw new IllegalArgumentException("Object is not an instance of " + relatedLocal.getName() +
": " + (proxy == null ? "null" : proxy.getClass().getName()));
}
final Bean newEntity = getEntityBean((EJBLocalObject) proxy);
if (newEntity == null) {
throw new IllegalArgumentException("Ejb has been deleted");
}
return add(newEntity);
}
public boolean remove(final Object o) {
if (!relatedLocal.isInstance(o)) {
return false;
}
final Bean entity = getEntityBean((EJBLocalObject) o);
final boolean changed = entity != null && getRelatedBeans(false, true).remove(entity);
if (changed && relatedProperty != null) {
toCmp2Entity(entity).OpenEJB_removeCmr(relatedProperty, source);
}
return changed;
}
private Bean getEntityBean(final EJBLocalObject proxy) {
if (proxy == null) {
return null;
}
final Bean bean = Cmp2Util.<Bean>getEntityBean(proxy);
return bean;
}
@Override
public EJBLocalObject getEJBLocalObject() throws IllegalStateException {
throw new UnsupportedOperationException();
}
public BeanContext(final String id, final Context jndiContext, final ModuleContext moduleContext,
final Class beanClass, final Class homeInterface,
final Class remoteInterface,
final Class localHomeInterface,
final Class localInterface,
final Class proxy,
final Class serviceEndpointInterface, final List<Class> businessLocals, final List<Class> businessRemotes, final Class pkClass,
final BeanType componentType,
final boolean localBean,
final boolean passivable) throws SystemException {
this(id, jndiContext, moduleContext, componentType, localBean, beanClass, passivable);
this.proxyClass = proxy;
if (homeInterface != null) {
this.getLegacyView().homeInterface = homeInterface;
}
if (localInterface != null) {
this.getLegacyView().localInterface = localInterface;
}
if (localHomeInterface != null) {
this.getLegacyView().localHomeInterface = localHomeInterface;
}
if (remoteInterface != null) {
this.getLegacyView().remoteInterface = remoteInterface;
}
if (businessLocals != null) {
this.businessLocals.addAll(businessLocals);
}
if (businessRemotes != null) {
this.businessRemotes.addAll(businessRemotes);
}
if (pkClass != null) {
getCmp().pkClass = pkClass;
}
this.serviceEndpointInterface = serviceEndpointInterface;
// if (businessLocal != null && localHomeInterface == null){
// this.localHomeInterface = BusinessLocalHome.class;
// }
//
// if (businessRemote != null && homeInterface == null){
// this.homeInterface = BusinessRemoteHome.class;
// }
// createMethodMap();
if (TimedObject.class.isAssignableFrom(beanClass)) {
try {
this.ejbTimeout = beanClass.getMethod("ejbTimeout", Timer.class);
} catch (final NoSuchMethodException e) {
throw new IllegalStateException(e);
}
}
addInterface(getServiceEndpointInterface(), InterfaceType.SERVICE_ENDPOINT);
addInterface(EJBHome.class, InterfaceType.EJB_HOME);
addInterface(EJBObject.class, InterfaceType.EJB_OBJECT);
addInterface(EJBLocalHome.class, InterfaceType.EJB_LOCAL_HOME);
addInterface(EJBLocalObject.class, InterfaceType.EJB_LOCAL);
addInterface(getHomeInterface(), InterfaceType.EJB_HOME);
addInterface(getRemoteInterface(), InterfaceType.EJB_OBJECT);
addInterface(getLocalHomeInterface(), InterfaceType.EJB_LOCAL_HOME);
addInterface(getLocalInterface(), InterfaceType.EJB_LOCAL);
addInterface(BeanContext.BusinessRemoteHome.class, InterfaceType.BUSINESS_REMOTE_HOME);
for (final Class businessRemote : this.businessRemotes) {
addInterface(businessRemote, InterfaceType.BUSINESS_REMOTE);
}
addInterface(BeanContext.BusinessLocalHome.class, InterfaceType.BUSINESS_LOCAL_HOME);
for (final Class businessLocal : this.businessLocals) {
addInterface(businessLocal, InterfaceType.BUSINESS_LOCAL);
}
if (localBean) {
addInterface(beanClass, InterfaceType.LOCALBEAN);
}
this.initDefaultLock();
}
private void check_localInterfaceMethods(final RemoteBean b) {
Class intrface = null;
Class beanClass = null;
try {
intrface = loadClass(b.getLocal());
beanClass = loadClass(b.getEjbClass());
} catch (final OpenEJBException e) {
return;
}
if (!EJBLocalObject.class.isAssignableFrom(intrface)) {
return;
}
final Method[] interfaceMethods = intrface.getMethods();
for (Method interfaceMethod : interfaceMethods) {
if (interfaceMethod.getDeclaringClass() == EJBLocalObject.class) {
continue;
}
final String name = interfaceMethod.getName();
try {
final Class[] params = interfaceMethod.getParameterTypes();
beanClass.getMethod(name, params);
} catch (final NoSuchMethodException nsme) {
final List<Method> differentArgs = new ArrayList<>();
final List<Method> differentCase = new ArrayList<>();
for (final Method method : beanClass.getMethods()) {
if (method.getName().equals(name)) {
differentArgs.add(method);
} else if (method.getName().equalsIgnoreCase(name)) {
differentCase.add(method);
}
}
if (differentArgs.size() > 0) {
fail(b, "no.busines.method.args", interfaceMethod.getName(), interfaceMethod.toString(), "local", intrface.getName(), beanClass.getName(), differentArgs.size());
}
if (differentCase.size() > 0) {
fail(b, "no.busines.method.case", interfaceMethod.getName(), interfaceMethod.toString(), "local", intrface.getName(), beanClass.getName(), differentCase.size());
}
if (differentArgs.size() == 0 && differentCase.size() == 0) {
fail(b, "no.busines.method", interfaceMethod.getName(), interfaceMethod.toString(), "local", intrface.getName(), beanClass.getName());
}
}
}
}
@Override
public Object invoke(final Object deployID,
InterfaceType type,
final Class callInterface,
final Method callMethod,
final Object[] args,
final Object primKey) throws OpenEJBException {
final BeanContext beanContext = this.getBeanContext(deployID);
if (beanContext == null) {
throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')");
}
// Use the backup way to determine call type if null was supplied.
if (type == null) {
type = beanContext.getInterfaceType(callInterface);
}
final ThreadContext callContext = new ThreadContext(beanContext, primKey);
final ThreadContext oldCallContext = ThreadContext.enter(callContext);
try {
final boolean authorized = type == InterfaceType.TIMEOUT || getSecurityService().isCallerAuthorized(callMethod, type);
if (!authorized) {
throw new ApplicationException(new EJBAccessException("Unauthorized Access by Principal Denied"));
}
final Class declaringClass = callMethod.getDeclaringClass();
final String methodName = callMethod.getName();
if (EJBHome.class.isAssignableFrom(declaringClass) || EJBLocalHome.class.isAssignableFrom(declaringClass)) {
if (declaringClass != EJBHome.class && declaringClass != EJBLocalHome.class) {
if (methodName.startsWith("create")) {
return createEJBObject(callMethod, args, callContext, type);
} else if (methodName.startsWith("find")) {
return findMethod(callMethod, args, callContext, type);
} else {
return homeMethod(callMethod, args, callContext, type);
}
} else if (methodName.equals("remove")) {
removeEJBObject(callMethod, args, callContext, type);
return null;
}
} else if ((EJBObject.class == declaringClass || EJBLocalObject.class == declaringClass) && methodName.equals("remove")) {
removeEJBObject(callMethod, args, callContext, type);
return null;
}
callContext.setCurrentOperation(type == InterfaceType.TIMEOUT ? Operation.TIMEOUT : Operation.BUSINESS);
final Method runMethod = beanContext.getMatchingBeanMethod(callMethod);
callContext.set(Method.class, runMethod);
return invoke(type, callMethod, runMethod, args, callContext);
} finally {
ThreadContext.exit(oldCallContext);
}
}
@Override
public Object invoke(final Object deployID,
InterfaceType type,
final Class callInterface,
final Method callMethod,
final Object[] args,
final Object primKey) throws OpenEJBException {
final BeanContext beanContext = this.getBeanContext(deployID);
if (beanContext == null) {
throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')");
}
// Use the backup way to determine call type if null was supplied.
if (type == null) {
type = beanContext.getInterfaceType(callInterface);
}
final ThreadContext callContext = new ThreadContext(beanContext, primKey);
final ThreadContext oldCallContext = ThreadContext.enter(callContext);
try {
final boolean authorized = securityService.isCallerAuthorized(callMethod, type);
if (!authorized) {
throw new ApplicationException(new EJBAccessException("Unauthorized Access by Principal Denied"));
}
final Class declaringClass = callMethod.getDeclaringClass();
final String methodName = callMethod.getName();
if (EJBHome.class.isAssignableFrom(declaringClass) || EJBLocalHome.class.isAssignableFrom(declaringClass)) {
if (declaringClass != EJBHome.class && declaringClass != EJBLocalHome.class) {
if (methodName.startsWith("create")) {
return createEJBObject(callMethod, args, callContext, type);
} else if (methodName.equals("findByPrimaryKey")) {
return findByPrimaryKey(callMethod, args, callContext, type);
} else if (methodName.startsWith("find")) {
return findEJBObject(callMethod, args, callContext, type);
} else {
return homeMethod(callMethod, args, callContext, type);
}
} else if (methodName.equals("remove")) {
removeEJBObject(callMethod, callContext, type);
return null;
}
} else if ((EJBObject.class == declaringClass || EJBLocalObject.class == declaringClass) && methodName.equals("remove")) {
removeEJBObject(callMethod, callContext, type);
return null;
}
// business method
callContext.setCurrentOperation(Operation.BUSINESS);
final Method runMethod = beanContext.getMatchingBeanMethod(callMethod);
callContext.set(Method.class, runMethod);
return businessMethod(callMethod, runMethod, args, callContext, type);
} finally {
ThreadContext.exit(oldCallContext);
}
}
@Override
public Object invoke(final Object deployID,
InterfaceType type,
final Class callInterface,
final Method callMethod,
final Object[] args,
final Object primKey) throws OpenEJBException {
final BeanContext beanContext = this.getBeanContext(deployID);
if (beanContext == null) {
throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')");
}
// Use the backup way to determine call type if null was supplied.
if (type == null) {
type = beanContext.getInterfaceType(callInterface);
}
final Method runMethod = beanContext.getMatchingBeanMethod(callMethod);
final ThreadContext callContext = new ThreadContext(beanContext, primKey);
final ThreadContext oldCallContext = ThreadContext.enter(callContext);
final CurrentCreationalContext currentCreationalContext = beanContext.get(CurrentCreationalContext.class);
Object runAs = null;
try {
if (oldCallContext != null) {
final BeanContext oldBc = oldCallContext.getBeanContext();
if (oldBc.getRunAsUser() != null || oldBc.getRunAs() != null) {
runAs = AbstractSecurityService.class.cast(securityService).overrideWithRunAsContext(callContext, beanContext, oldBc);
}
}
final boolean authorized = type == InterfaceType.TIMEOUT || getSecurityService().isCallerAuthorized(callMethod, type);
if (!authorized) {
throw new org.apache.openejb.ApplicationException(new EJBAccessException("Unauthorized Access by Principal Denied"));
}
final Class declaringClass = callMethod.getDeclaringClass();
if (EJBHome.class.isAssignableFrom(declaringClass) || EJBLocalHome.class.isAssignableFrom(declaringClass)) {
if (callMethod.getName().startsWith("create")) {
return createEJBObject(beanContext, callMethod);
} else {
return null;// EJBHome.remove( ) and other EJBHome methods are not process by the container
}
} else if (EJBObject.class == declaringClass || EJBLocalObject.class == declaringClass) {
return null;// EJBObject.remove( ) and other EJBObject methods are not process by the container
}
final Instance instance = instanceManager.getInstance(callContext);
callContext.setCurrentOperation(type == InterfaceType.TIMEOUT ? Operation.TIMEOUT : Operation.BUSINESS);
callContext.setCurrentAllowedStates(null);
callContext.set(Method.class, runMethod);
callContext.setInvokedInterface(callInterface);
if (currentCreationalContext != null) {
//noinspection unchecked
currentCreationalContext.set(instance.creationalContext);
}
return _invoke(callMethod, runMethod, args, instance, callContext, type);
} finally {
if (runAs != null) {
try {
securityService.associate(runAs);
} catch (final LoginException e) {
// no-op
}
}
ThreadContext.exit(oldCallContext);
if (currentCreationalContext != null) {
currentCreationalContext.remove();
}
}
}
/**
* Release the given EJB instance.
* Default implementation delegates to removeSessionBeanInstance.
* @param ejb the EJB instance to release
* @see #removeSessionBeanInstance
*/
protected void releaseSessionBeanInstance(EJBLocalObject ejb) {
removeSessionBeanInstance(ejb);
}
/**
* Release the given EJB instance.
* Default implementation delegates to removeSessionBeanInstance.
* @param ejb the EJB instance to release
* @see #removeSessionBeanInstance
*/
protected void releaseSessionBeanInstance(EJBLocalObject ejb) {
removeSessionBeanInstance(ejb);
}
/**
* Release the given EJB instance.
* Default implementation delegates to removeSessionBeanInstance.
* @param ejb the EJB instance to release
* @see #removeSessionBeanInstance
*/
protected void releaseSessionBeanInstance(EJBLocalObject ejb) {
removeSessionBeanInstance(ejb);
}
/**
* Release the given EJB instance.
* Default implementation delegates to removeSessionBeanInstance.
* @param ejb the EJB instance to release
* @see #removeSessionBeanInstance
*/
protected void releaseSessionBeanInstance(EJBLocalObject ejb) {
removeSessionBeanInstance(ejb);
}
private boolean isValidInterface(final RemoteBean b, final Class clazz, final Class beanClass, final String tag) {
if (clazz.equals(beanClass)) {
fail(b, "xml." + tag + ".beanClass", clazz.getName());
} else if (!clazz.isInterface()) {
fail(b, "xml." + tag + ".notInterface", clazz.getName());
} else if (EJBHome.class.isAssignableFrom(clazz)) {
if (tag.equals("home")) {
return true;
}
fail(b, "xml." + tag + ".ejbHome", clazz.getName());
} else if (EJBLocalHome.class.isAssignableFrom(clazz)) {
if (tag.equals("localHome")) {
return true;
}
fail(b, "xml." + tag + ".ejbLocalHome", clazz.getName());
} else if (EJBObject.class.isAssignableFrom(clazz)) {
if (tag.equals("remote")) {
return true;
}
fail(b, "xml." + tag + ".ejbObject", clazz.getName());
} else if (EJBLocalObject.class.isAssignableFrom(clazz)) {
if (tag.equals("local")) {
return true;
}
fail(b, "xml." + tag + ".ejbLocalObject", clazz.getName());
} else {
if (tag.equals("businessLocal") || tag.equals("businessRemote")) {
return true;
} else if (clazz.isAnnotationPresent(Local.class)) {
fail(b, "xml." + tag + ".businessLocal", clazz.getName());
} else if (clazz.isAnnotationPresent(Remote.class)) {
fail(b, "xml." + tag + ".businessRemote", clazz.getName());
} else {
fail(b, "xml." + tag + ".unknown", clazz.getName());
}
}
// must be tagged as <home>, <local-home>, <remote>, or <local>
return false;
}