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.marshall;
023:
024: import org.jboss.invocation.Invocation;
025: import org.jboss.invocation.MarshalledInvocation;
026: import org.jboss.logging.Logger;
027: import org.jboss.remoting.InvocationRequest;
028: import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
029: import org.jboss.remoting.marshal.Marshaller;
030: import org.jboss.remoting.marshal.MarshallerDecorator;
031: import org.jboss.tm.TransactionPropagationContextFactory;
032: import org.jboss.tm.TransactionPropagationContextUtil;
033:
034: import javax.transaction.SystemException;
035: import java.io.IOException;
036: import java.io.OutputStream;
037:
038: /**
039: * This marshaller is to be used in conjunction with the UnifiedInvoker and will
040: * look for an InvocationRequest to be passed to it, which is specific to EJB
041: * invocations.
042: *
043: * @author <a href="mailto:tom@jboss.org">Tom Elrod</a>
044: */
045: public class InvocationMarshaller extends SerializableMarshaller
046: implements MarshallerDecorator {
047: /** @since 4.2.0 */
048: static final long serialVersionUID = -2109634245396128775L;
049:
050: public final static String DATATYPE = "invocation";
051:
052: private static final Logger log = Logger
053: .getLogger(InvocationMarshaller.class);
054:
055: /**
056: * Marshaller will need to take the dataObject and convert
057: * into primitive java data types and write to the
058: * given output. Will check to see if dataObject being passed is
059: * an InvocationRequest, and if is, process it (including handling propagation of
060: * transaction). If is not an instance of InvocationRequest, will default back to
061: * SerializableMarshaller for processing.
062: *
063: * @param dataObject Object to be writen to output
064: * @param output The data output to write the object
065: * data to.
066: */
067: public void write(Object dataObject, OutputStream output)
068: throws IOException {
069:
070: super .write(addDecoration(dataObject), output);
071: }
072:
073: public void write(Object dataObject, OutputStream output,
074: int version) throws IOException {
075:
076: super .write(addDecoration(dataObject), output, version);
077: }
078:
079: public Object addDecoration(Object dataObject) throws IOException {
080: if (dataObject instanceof InvocationRequest) {
081: InvocationRequest remoteInv = (InvocationRequest) dataObject;
082:
083: if (remoteInv.getParameter() instanceof Invocation) {
084: Invocation inv = (Invocation) remoteInv.getParameter();
085:
086: MarshalledInvocation marshInv = new MarshalledInvocation(
087: inv);
088:
089: if (inv != null) {
090: // now that have invocation object related to ejb invocations,
091: // need to get the possible known payload objects and make sure
092: // they get serialized.
093:
094: try {
095: marshInv
096: .setTransactionPropagationContext(getTransactionPropagationContext());
097: } catch (SystemException e) {
098: log
099: .error(
100: "Error setting transaction propagation context.",
101: e);
102: throw new IOException(
103: "Error setting transaction context. Message: "
104: + e.getMessage());
105: }
106:
107: // reset the invocation parameter within remote invocation
108: remoteInv.setParameter(marshInv);
109: } else {
110: //Should never get here, but will check anyways
111: log
112: .error("Attempting to marshall Invocation but is null. Can not proceed.");
113: throw new IOException(
114: "Can not process data object due to the InvocationRequest's parameter being null.");
115: }
116:
117: }
118: }
119: return dataObject;
120: }
121:
122: public Object getTransactionPropagationContext()
123: throws SystemException {
124: TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil
125: .getTPCFactoryClientSide();
126: return (tpcFactory == null) ? null : tpcFactory
127: .getTransactionPropagationContext();
128: }
129:
130: public Marshaller cloneMarshaller()
131: throws CloneNotSupportedException {
132: return new InvocationMarshaller();
133: }
134:
135: }
|