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: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Mikhail A. Markov
021: * @version $Revision: 1.1.2.2 $
022: */package org.apache.harmony.rmi.server;
023:
024: import java.io.IOException;
025: import java.io.ObjectInput;
026: import java.io.ObjectOutput;
027: import java.rmi.server.ObjID;
028: import java.rmi.server.RemoteRef;
029:
030: import org.apache.harmony.rmi.transport.Endpoint;
031: import org.apache.harmony.rmi.transport.RMIObjectInputStream;
032: import org.apache.harmony.rmi.transport.RMIObjectOutputStream;
033:
034: /**
035: * Base class for all RemoteRef implementations.
036: * It belongs to org.apache.harmony.rmi.transport package because it should have
037: * package protected access to ClientDGC implementation.
038: *
039: * @author Mikhail A. Markov
040: * @version $Revision: 1.1.2.2 $
041: */
042: public abstract class RemoteRefBase implements RemoteRef {
043:
044: private static final long serialVersionUID = 358378173612121423L;
045:
046: /** Endpoint this handle refers to. */
047: protected Endpoint ep;
048:
049: /** Object ID of remote object. */
050: protected ObjID objId;
051:
052: /** True if this handle is for local object. */
053: protected boolean isLocal;
054:
055: /**
056: * Returns Object ID for the referenced remote object.
057: *
058: * @return Object ID for the referenced remote object
059: */
060: public ObjID getObjId() {
061: return objId;
062: }
063:
064: /**
065: * @see RemoteRef.remoteEquals(RemoteRef)
066: */
067: public boolean remoteEquals(RemoteRef obj) {
068: if (!(obj instanceof RemoteRefBase)) {
069: return false;
070: }
071: RemoteRefBase ref = (RemoteRefBase) obj;
072: return ep.equals(ref.ep) && (objId.equals(ref.objId));
073: }
074:
075: /**
076: * @see RemoteRef.remoteToString()
077: */
078: public String remoteToString() {
079: return getRefClass(null)
080: + "[endpoint:[" + ep + "]" //$NON-NLS-1$ //$NON-NLS-2$
081: + ((isLocal) ? "(local)" : "(remote)") + ", " + objId + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
082: }
083:
084: /**
085: * Returns the value returned by remoteToString() method.
086: *
087: * @return the value returned by remoteToString() method
088: */
089: public String toString() {
090: return remoteToString();
091: }
092:
093: /**
094: * @see RemoteRef.remoteHashCode()
095: */
096: public int remoteHashCode() {
097: return ((objId != null) ? objId.hashCode() : super .hashCode());
098: }
099:
100: /**
101: * Reads everything left except Endpoint info from the given stream and
102: * detects if DGC ack is needed.
103: *
104: * @param in the stream to read data from
105: *
106: * @throws IOException if any I/O error occurred
107: * @throws ClassNotFoundException if class could not be loaded by current
108: * class loader
109: */
110: protected void readCommon(ObjectInput in) throws IOException,
111: ClassNotFoundException {
112: objId = ObjID.read(in);
113: boolean needAck = in.readBoolean();
114:
115: if (in instanceof RMIObjectInputStream) {
116: RMIObjectInputStream oin = (RMIObjectInputStream) in;
117:
118: if (oin.isRemoteCallStream()) {
119: oin.needDGCAck(needAck);
120: }
121: }
122: RMIObjectInfo info = ExportManager.getInfo(objId);
123:
124: if ((info == null) || !info.sref.remoteEquals(this )) {
125: /*
126: * This remote object created in another VM so
127: * register it in ClientDGC.
128: */
129: ClientDGC.registerForRenew(this );
130: }
131: }
132:
133: /**
134: * Writes everything left except Endpoint info to the given stream.
135: *
136: * @param out the stream to write the object to
137: *
138: * @throws IOException if any I/O error occurred or class is not serializable
139: */
140: protected void writeCommon(ObjectOutput out) throws IOException {
141: objId.write(out);
142: boolean isResStream = false;
143:
144: if (out instanceof RMIObjectOutputStream) {
145: RMIObjectOutputStream oout = (RMIObjectOutputStream) out;
146: isResStream = oout.isResultStream();
147:
148: if (isResStream) {
149: /*
150: * Because this is a result stream (i.e. obtained in
151: * RemoteCall.getResultStream() method), after writing all
152: * objects we will wait for DGC ack call. So, we should register
153: * this ref for holding a strong reference to the referenced
154: * remote object.
155: */
156: ClientDGC.registerForDGCAck(oout.getUID(), this);
157: }
158: }
159: out.writeBoolean(isResStream);
160: }
161: }
|