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.pooled.interfaces;
023:
024: import org.jboss.invocation.Invocation;
025: import org.jboss.invocation.InvocationType;
026: import org.jboss.invocation.MarshalledInvocation;
027: import org.jboss.invocation.MarshalledValue;
028:
029: import javax.transaction.Transaction;
030: import java.io.IOException;
031: import java.lang.reflect.Method;
032: import java.security.Principal;
033: import java.util.HashMap;
034: import java.util.Iterator;
035:
036: /**
037: * The MarshalledInvocation is an invocation that travels. As such it
038: * serializes its payload because of lack of ClassLoader visibility. As such it
039: * contains Marshalled data representing the byte[] of the Invocation object it
040: * extends Besides handling the specifics of "marshalling" the payload, which
041: * could be done at the Invocation level the Marshalled Invocation can hold
042: * optimization and needed code for distribution for example the
043: * TransactionPropagationContext which is a serialization of the TX for
044: * distribution purposes as well as the "hash" for the methods that we send, as
045: * opposed to sending Method objects. Serialization "optimizations" should be
046: * coded here in the externalization implementation of the class
047: *
048: * @author <a href="mailto:marc@jboss.org">Marc Fleury</a>
049: * @version $Revision: 57209 $
050: */
051: public class PooledMarshalledInvocation extends MarshalledInvocation
052: implements java.io.Externalizable {
053: // Constants -----------------------------------------------------
054:
055: /**
056: * Serial Version Identifier.
057: */
058: static final long serialVersionUID = -728630295444149842L;
059:
060: private transient Transaction tx;
061: private transient Object credential;
062: private transient Principal principal;
063: private transient Object enterpriseContext;
064: private transient Object id;
065: private transient PooledMarshalledValue pooledMarshalledArgs;
066:
067: // Constructors --------------------------------------------------
068: public PooledMarshalledInvocation() {
069: // For externalization to work
070: }
071:
072: public PooledMarshalledInvocation(Invocation invocation) {
073: this .payload = invocation.payload;
074: this .as_is_payload = invocation.as_is_payload;
075: this .method = invocation.getMethod();
076: this .objectName = invocation.getObjectName();
077: this .args = invocation.getArguments();
078: this .invocationType = invocation.getType();
079: }
080:
081: public PooledMarshalledInvocation(Object id, Method m,
082: Object[] args, Transaction tx, Principal identity,
083: Object credential) {
084: super (id, m, args, tx, identity, credential);
085: }
086:
087: // Public --------------------------------------------------------
088:
089: public Object getEnterpriseContext() {
090: return enterpriseContext;
091: }
092:
093: public void setEnterpriseContext(Object enterpriseContext) {
094: this .enterpriseContext = enterpriseContext;
095: }
096:
097: public Object getId() {
098: if (id == null)
099: id = super .getId();
100: return id;
101: }
102:
103: public void setId(Object id) {
104: super .setId(id);
105: this .id = id;
106: }
107:
108: public void setTransaction(Transaction tx) {
109: super .setTransaction(tx);
110: this .tx = tx;
111: }
112:
113: public Transaction getTransaction() {
114: if (tx == null)
115: tx = super .getTransaction();
116: return this .tx;
117: }
118:
119: public Object getCredential() {
120: if (credential == null)
121: credential = super .getCredential();
122: return credential;
123: }
124:
125: public void setCredential(Object credential) {
126: super .setCredential(credential);
127: this .credential = credential;
128: }
129:
130: public Principal getPrincipal() {
131: if (principal == null)
132: principal = super .getPrincipal();
133: return principal;
134: }
135:
136: public void setPrincipal(Principal principal) {
137: super .setPrincipal(principal);
138: this .principal = principal;
139: }
140:
141: public Object[] getArguments() {
142: if (this .args == null) {
143: try {
144: this .args = (Object[]) pooledMarshalledArgs.get();
145: } catch (Exception e) {
146: e.printStackTrace();
147: }
148: }
149: return args;
150: }
151:
152: // Externalizable implementation ---------------------------------
153: public void writeExternal(java.io.ObjectOutput out)
154: throws IOException {
155: out.writeObject(invocationType);
156: // FIXME marcf: the "specific" treatment of Transactions should be abstracted.
157: // Write the TPC, not the local transaction
158: out.writeObject(tpc);
159:
160: long methodHash = calculateHash(this .method);
161: out.writeLong(methodHash);
162:
163: out.writeInt(((Integer) this .objectName).intValue());
164: out.writeObject(new PooledMarshalledValue(this .args));
165:
166: // Write out payload hashmap
167: // Don't use hashmap serialization to avoid not-needed data being
168: // marshalled
169: // The map contains only serialized representations of every other object
170: // Everything else is possibly tied to classloaders that exist inside the
171: // server but not in the generic JMX land. they will travel in the payload
172: // as MarshalledValue objects, see the Invocation getter logic
173: //
174: if (payload == null)
175: out.writeInt(0);
176: else {
177: out.writeInt(payload.size());
178: Iterator keys = payload.keySet().iterator();
179: while (keys.hasNext()) {
180: Object currentKey = keys.next();
181:
182: // This code could be if (object.getClass().getName().startsWith("java")) then don't serialize.
183: // Bench the above for speed.
184:
185: out.writeObject(currentKey);
186: out.writeObject(new MarshalledValue(payload
187: .get(currentKey)));
188: }
189: }
190:
191: // This map is "safe" as is
192: //out.writeObject(as_is_payload);
193: if (as_is_payload == null)
194: out.writeInt(0);
195: else {
196: out.writeInt(as_is_payload.size());
197:
198: Iterator keys = as_is_payload.keySet().iterator();
199: while (keys.hasNext()) {
200: Object currentKey = keys.next();
201: out.writeObject(currentKey);
202: out.writeObject(as_is_payload.get(currentKey));
203: }
204: }
205: }
206:
207: public void readExternal(java.io.ObjectInput in)
208: throws IOException, ClassNotFoundException {
209: invocationType = (InvocationType) in.readObject();
210: tpc = in.readObject();
211: this .methodHash = in.readLong();
212:
213: this .objectName = new Integer(in.readInt());
214:
215: pooledMarshalledArgs = (PooledMarshalledValue) in.readObject();
216:
217: int payloadSize = in.readInt();
218: if (payloadSize > 0) {
219: payload = new HashMap();
220: for (int i = 0; i < payloadSize; i++) {
221: Object key = in.readObject();
222: Object value = in.readObject();
223: payload.put(key, value);
224: }
225: }
226:
227: int as_is_payloadSize = in.readInt();
228: if (as_is_payloadSize > 0) {
229: as_is_payload = new HashMap();
230: for (int i = 0; i < as_is_payloadSize; i++) {
231: Object key = in.readObject();
232: Object value = in.readObject();
233: as_is_payload.put(key, value);
234: }
235: }
236: }
237: }
|