001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.invocation.unified.interfaces;
023:
024: import java.io.Externalizable;
025: import java.io.IOException;
026: import java.io.ObjectInput;
027: import java.io.ObjectOutput;
028: import java.io.StreamCorruptedException;
029: import java.rmi.MarshalledObject;
030: import java.rmi.RemoteException;
031: import java.rmi.ServerException;
032: import org.jboss.invocation.Invocation;
033: import org.jboss.invocation.Invoker;
034: import org.jboss.logging.Logger;
035: import org.jboss.remoting.Client;
036: import org.jboss.remoting.InvokerLocator;
037: import org.jboss.remoting.serialization.IMarshalledValue;
038:
039: /**
040: * This represents the client side of the EJB invoker. This invoker uses
041: * the remoting framework for making invocations.
042: *
043: * @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
044: */
045: public class UnifiedInvokerProxy implements Invoker, Externalizable {
046: static {
047: try {
048: Class
049: .forName("org.jboss.invocation.unified.interfaces.JavaSerializationManager");
050: } catch (Exception e) {
051: }
052: }
053:
054: static final long serialVersionUID = -1108158470271861548L;
055:
056: private transient Client client;
057:
058: private InvokerLocator locator;
059:
060: private boolean strictRMIException = false;
061:
062: private String subsystem = "invoker";
063:
064: protected final Logger log = Logger.getLogger(getClass());
065:
066: static final int VERSION_5_0 = 500;
067: static final int CURRENT_VERSION = VERSION_5_0;
068:
069: public UnifiedInvokerProxy() {
070: super ();
071: }
072:
073: public UnifiedInvokerProxy(InvokerLocator locator) {
074: init(locator);
075: }
076:
077: public UnifiedInvokerProxy(InvokerLocator locator,
078: boolean isStrictRMIException) {
079: this .strictRMIException = isStrictRMIException;
080: init(locator);
081: }
082:
083: protected void init(InvokerLocator locator) {
084: this .locator = locator;
085:
086: try {
087: client = new Client(locator, getSubSystem());
088: client.connect();
089: } catch (Exception e) {
090: log.fatal("Could not initialize UnifiedInvokerProxy.", e);
091: }
092:
093: }
094:
095: public String getSubSystem() {
096: return subsystem;
097: }
098:
099: public void setSubSystem(String subsystem) {
100: this .subsystem = subsystem;
101: }
102:
103: public boolean isStrictRMIException() {
104: return strictRMIException;
105: }
106:
107: protected Client getClient() {
108: return client;
109: }
110:
111: protected InvokerLocator getLocator() {
112: return locator;
113: }
114:
115: protected void setLocator(InvokerLocator locator) {
116: this .locator = locator;
117: }
118:
119: protected void setStrictRMIException(boolean strictRMIException) {
120: this .strictRMIException = strictRMIException;
121: }
122:
123: /**
124: * A free form String identifier for this delegate invoker, can be clustered or target node
125: * This should evolve in a more advanced meta-inf object.
126: * <p/>
127: * This will return the host supplied by the invoker locator if locator is not null. Otherwise, if the locator is null, will
128: * return null.
129: */
130: public String getServerHostName() throws Exception {
131: if (locator != null) {
132: return locator.getHost();
133: } else {
134: return null;
135: }
136: }
137:
138: /**
139: * @param invocation A pointer to the invocation object
140: * @return Return value of method invocation.
141: * @throws Exception Failed to invoke method.
142: */
143: public Object invoke(Invocation invocation) throws Exception {
144: Object response = null;
145:
146: // Earlier versions of InvokerLocator don't have a findSerializationType() method.
147: try {
148: invocation.getInvocationContext().setValue(
149: "SERIALIZATION_TYPE",
150: locator.findSerializationType());
151: } catch (NoSuchMethodError e) {
152: invocation.getInvocationContext().setValue(
153: "SERIALIZATION_TYPE", "java");
154: }
155:
156: try {
157: response = client.invoke(invocation, null);
158:
159: if (response instanceof Exception) {
160: throw ((Exception) response);
161: }
162: if (response instanceof MarshalledObject) {
163: return ((MarshalledObject) response).get();
164: }
165: if (response instanceof IMarshalledValue) {
166: return ((IMarshalledValue) response).get();
167: }
168: return response;
169:
170: } catch (RemoteException aex) {
171: // per Jira issue JBREM-61
172: if (strictRMIException) {
173: throw new ServerException(aex.getMessage(), aex);
174: } else {
175: throw aex;
176: }
177: } catch (Throwable throwable) {
178: // this is somewhat of a hack as remoting throws throwable,
179: // so will let Exception types bubble up, but if Throwable type,
180: // then have to wrap in new Exception, as this is the signature
181: // of this invoke method.
182: if (throwable instanceof Exception) {
183: throw (Exception) throwable;
184: }
185: throw new Exception(throwable);
186: }
187: }
188:
189: /**
190: * Externalize this instance and handle obtaining the remoteInvoker stub
191: */
192: public void writeExternal(final ObjectOutput out)
193: throws IOException {
194: out.writeInt(CURRENT_VERSION);
195:
196: out.writeUTF(locator.getOriginalURI());
197: out.writeBoolean(strictRMIException);
198: }
199:
200: /**
201: * Un-externalize this instance.
202: */
203: public void readExternal(final ObjectInput in) throws IOException,
204: ClassNotFoundException {
205: int version = in.readInt();
206: // Read in and map the version of the serialized data seen
207: switch (version) {
208: case VERSION_5_0:
209: locator = new InvokerLocator(in.readUTF());
210: strictRMIException = in.readBoolean();
211: init(locator);
212: break;
213: default:
214: throw new StreamCorruptedException("Unknown version seen: "
215: + version);
216: }
217: }
218:
219: }
|