001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.core.entity;
017:
018: import java.lang.reflect.Method;
019: import java.util.List;
020: import java.io.Serializable;
021:
022: import org.apache.openejb.Container;
023: import org.apache.openejb.InterfaceType;
024: import org.apache.openejb.DeploymentInfo;
025: import org.apache.openejb.core.ivm.EjbObjectProxyHandler;
026: import org.apache.openejb.util.proxy.ProxyManager;
027:
028: public class EntityEjbObjectHandler extends EjbObjectProxyHandler {
029:
030: /*
031: * The registryId is a logical identifier that is used as a key when placing EntityEjbObjectHandler into
032: * the BaseEjbProxyHanlder's liveHandleRegistry. EntityEjbObjectHandlers that represent the same
033: * bean identity (keyed by the registry id) will be stored together so that they can be removed together
034: * when the BaseEjbProxyHandler.invalidateAllHandlers is invoked. The EntityEjbObjectHandler uses a
035: * compound key composed of the entity bean's primary key, deployment id, and
036: * container id. This uniquely identifies the bean identity that is proxied by this handler allowing it
037: * to be removed with other handlers bound to the same registry id.
038: */
039: private Object registryId;
040:
041: public EntityEjbObjectHandler(DeploymentInfo deploymentInfo,
042: Object pk, InterfaceType interfaceType,
043: List<Class> interfaces) {
044: super (deploymentInfo, pk, interfaceType, interfaces);
045: }
046:
047: /*
048: * This method generates a logically unique entity bean identifier from the primary key,
049: * deployment id, and container id. This registry key is then used as an index for the associated
050: * entity bean in the BaseEjbProxyHandler.liveHandleRegistry. The liveHandleRegistry tracks
051: * handler for the same bean identity so that they can removed together when one of the remove() operations
052: * is called.
053: */
054: public static Object getRegistryId(Container container,
055: Object deploymentId, Object primaryKey) {
056: return new RegistryId(container, deploymentId, primaryKey);
057: }
058:
059: public Object getRegistryId() {
060: if (registryId == null) {
061: registryId = getRegistryId(container, deploymentID,
062: primaryKey);
063: }
064: return registryId;
065: }
066:
067: protected Object getPrimaryKey(Method method, Object[] args,
068: Object proxy) throws Throwable {
069: return primaryKey;
070: }
071:
072: protected Object isIdentical(Method method, Object[] args,
073: Object proxy) throws Throwable {
074: checkAuthorization(method);
075:
076: if (args.length != 1) {
077: throw new IllegalArgumentException(
078: "Expected one argument to isIdentical, but received "
079: + args.length);
080: }
081:
082: Object that = args[0];
083: Object invocationHandler = ProxyManager
084: .getInvocationHandler(that);
085:
086: if (invocationHandler instanceof EntityEjbObjectHandler) {
087: EntityEjbObjectHandler handler = (EntityEjbObjectHandler) invocationHandler;
088:
089: /*
090: * The registry id is a compound key composed of the bean's primary key, deployment id, and
091: * container id. It uniquely identifies the entity bean that is proxied by the EntityEjbObjectHandler
092: * within the IntraVM.
093: */
094: return this .getRegistryId().equals(handler.getRegistryId());
095: }
096: return false;
097: }
098:
099: protected Object remove(Class interfce, Method method,
100: Object[] args, Object proxy) throws Throwable {
101: checkAuthorization(method);
102: Object value = container.invoke(deploymentID, interfce, method,
103: args, primaryKey);
104: /*
105: * This operation takes care of invalidating all the EjbObjectProxyHanders associated with
106: * the same RegistryId. See this.createProxy().
107: */
108: invalidateAllHandlers(getRegistryId());
109: return value;
110: }
111:
112: public void invalidateReference() {
113: // entity bean object references should not be invalidated since they
114: // will automatically hook up to a new instance of the bean using the
115: // primary key (we will load a new instance from the db)
116: }
117:
118: private static class RegistryId implements Serializable {
119: private static final long serialVersionUID = -6009230402616418827L;
120:
121: private final Object containerId;
122: private final Object deploymentId;
123: private final Object primaryKey;
124:
125: public RegistryId(Container container, Object deploymentId,
126: Object primaryKey) {
127: if (container == null)
128: throw new NullPointerException("container is null");
129: if (deploymentId == null)
130: throw new NullPointerException("deploymentId is null");
131:
132: this .containerId = container.getContainerID();
133: this .deploymentId = deploymentId;
134: this .primaryKey = primaryKey;
135: }
136:
137: public boolean equals(Object o) {
138: if (this == o)
139: return true;
140: if (o == null || getClass() != o.getClass())
141: return false;
142:
143: RegistryId that = (RegistryId) o;
144:
145: return containerId.equals(that.containerId)
146: && deploymentId.equals(that.deploymentId)
147: && !(primaryKey != null ? !primaryKey
148: .equals(that.primaryKey)
149: : that.primaryKey != null);
150: }
151:
152: public int hashCode() {
153: int result;
154: result = containerId.hashCode();
155: result = 31 * result + deploymentId.hashCode();
156: result = 31 * result
157: + (primaryKey != null ? primaryKey.hashCode() : 0);
158: return result;
159: }
160:
161: public String toString() {
162: return "[" + containerId + ", " + deploymentId + ", "
163: + primaryKey + "]";
164: }
165: }
166: }
|