Package org.apache.yoko.bindings.corba.interceptors

Source Code of org.apache.yoko.bindings.corba.interceptors.CorbaInInterceptor

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.yoko.bindings.corba.interceptors;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.ws.Holder;

import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxb.JAXBUtils;
import org.apache.cxf.jaxb.WrapperHelper;
import org.apache.cxf.jaxb.io.EventDataReader;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.service.model.MessageInfo;
import org.apache.cxf.service.model.MessagePartInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.apache.schemas.yoko.bindings.corba.ArgType;
import org.apache.schemas.yoko.bindings.corba.ModeType;
import org.apache.schemas.yoko.bindings.corba.OperationType;
import org.apache.schemas.yoko.bindings.corba.ParamType;
import org.apache.schemas.yoko.bindings.corba.TypeMappingType;
import org.apache.yoko.bindings.corba.ContextUtils;
import org.apache.yoko.bindings.corba.CorbaDestination;
import org.apache.yoko.bindings.corba.CorbaMessage;
import org.apache.yoko.bindings.corba.CorbaStaxObject;
import org.apache.yoko.bindings.corba.CorbaStreamable;
import org.apache.yoko.bindings.corba.CorbaTypeMap;
import org.apache.yoko.bindings.corba.CorbaUtils;
import org.apache.yoko.bindings.corba.types.CorbaHandlerUtils;
import org.apache.yoko.bindings.corba.types.CorbaObjectHandler;
import org.apache.yoko.wsdl.CorbaConstants;
import org.omg.CORBA.Any;
import org.omg.CORBA.NVList;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ServerRequest;

public class CorbaInInterceptor extends AbstractPhaseInterceptor<Message> {
   
    protected static CorbaStaxObject corbaStaxObject;
    private List<CorbaTypeMap> typeMaps;
    private XMLOutputFactory xof;
    private XMLInputFactory xif;
    private ORB orb;
    private ServiceInfo service;
   
    public CorbaInInterceptor() {
        super();
        setPhase(Phase.UNMARSHAL);
        corbaStaxObject = new CorbaStaxObject();
    }
   
    public void setOrb(ORB mOrb) {
        orb = mOrb;
    }

    public void handleMessage(Message msg) {
        try {
            CorbaMessage message = (CorbaMessage) msg;
              
            CorbaDestination destination = null;
            if (message.getDestination() != null) {
                destination = (CorbaDestination)message.getDestination();
            } else {
                destination = (CorbaDestination)message.getExchange().getDestination();
            }
       
            typeMaps = new ArrayList<CorbaTypeMap>();               
            service = destination.getBindingInfo().getService();
            List<TypeMappingType> corbaTypes = service.getDescription().getExtensors(TypeMappingType.class);
            if (corbaTypes != null) {
                CorbaUtils.createCorbaTypeMap(typeMaps, corbaTypes);
                corbaStaxObject.setTypeMaps(typeMaps);
                corbaStaxObject.setServiceInfo(service);
            }
           
            // TODO: where does encoding constant go?
            //String encoding = (String)message.get("Encoding");       
                              
            // check to see if we have an input or output message
            if (!ContextUtils.isRequestor(msg)) {
                handleNotRequestMessage(message, destination);               
            } else {            
                handleRequestMessage(message, destination);
            }
        } catch (Exception ex) {
            throw new Fault(ex);
        }
    }
           
    protected void handleNotRequestMessage(CorbaMessage message,
                                           CorbaDestination destination)
        throws Exception {
        QName opQName = null;
        OperationType opType = null;
        BindingInfo bInfo = destination.getBindingInfo();             
        InterfaceInfo info = bInfo.getInterface();       
        EventDataReader reader = (EventDataReader) ContextUtils.getDataReader(message);
        
        Exchange exchange = message.getExchange();
        orb = (ORB)exchange.get(ORB.class);
        if (corbaStaxObject != null) {
            corbaStaxObject.setOrb(orb);
        } else {
            corbaStaxObject = new CorbaStaxObject(orb);
        }

        String opName = message.getExchange().get(String.class);
        Iterator i = bInfo.getOperations().iterator();

        BindingOperationInfo bopInfo = null;
        while (i.hasNext()) {
            bopInfo = (BindingOperationInfo)i.next();
            if (bopInfo.getName().getLocalPart().equals(opName)) {
                opType = bopInfo.getExtensor(OperationType.class);
                opQName = bopInfo.getName();
                break;
            }
        }
        ServerRequest request = exchange.get(ServerRequest.class);
        NVList list = prepareArguments(message, destination, info, opType, opQName);
        request.arguments(list);
        message.setList(list);           
   
        OperationInfo opInfo = processWrappedOperation(bopInfo, false);

        addUnmarshalParams(message,
                           message,
                           info,
                           opType,
                           opInfo,
                           reader,
                           false);
        addWrapperParams(message, bopInfo, false);
       
    }
   
    protected void handleRequestMessage(CorbaMessage message,
                                        CorbaDestination destination)
        throws Exception {
        OperationType opType = null;
       
        orb = (org.omg.CORBA.ORB) message.get(CorbaConstants.ORB)
        if (corbaStaxObject != null) {
            corbaStaxObject.setOrb(orb);
        } else {
            corbaStaxObject = new CorbaStaxObject(orb);
        }
        if (message.getStreamableException() != null) {
            Endpoint ep = message.getExchange().get(Endpoint.class);
            message.getInterceptorChain().abort();
            if (ep.getInFaultObserver() != null) {
                ep.getInFaultObserver().onMessage(message);
                return;
            }
        }

        EventDataReader reader;
        reader = (EventDataReader) ContextUtils.getDataReader(message);
        BindingInfo bInfo = destination.getBindingInfo();             
        InterfaceInfo info = bInfo.getInterface();
       
        Exchange exchange = message.getExchange();
        BindingOperationInfo bopInfo = exchange.get(BindingOperationInfo.class);

        // Handle the parameters that are given for the operation
        List<ParamType> paramTypes = null;    
        ArgType argType = null;
       
        if (opType != null) {
            paramTypes = opType.getParam();    
            argType = opType.getReturn();
        }
        CorbaMessage outMessage = (CorbaMessage)exchange.getOutMessage();
       
        opType = bopInfo.getExtensor(OperationType.class);

        OperationInfo opInfo = processWrappedOperation(bopInfo, true);

        writeReturnValue(message, outMessage, opInfo, argType, reader);

        addUnmarshalParams(outMessage,
                           message,
                           info,
                           opType,
                           opInfo,
                           reader,
                           true);
        addWrapperParams(message, bopInfo, true);
    }


    /**
     * REVISIT, hack to workaround 2 problems with cxf
     * 1. the message part type class is not set for inner parts w.r.t wrapped doc-style wsdl
     * 2. Since corba binding doesn't depend on wrapped doc-style, there is no need for cxf jaxws
     * WrapperClassIn & WrapperClassOut interceptors.
     */
    protected void addWrapperParams(Message message, BindingOperationInfo bopInfo, boolean isOutput)
        throws Exception {
        if (bopInfo.isUnwrappedCapable()) {
            OperationInfo opInfo = bopInfo.getOperationInfo();

            MessageInfo msgInfo = null;
            if (isOutput) {
                msgInfo = opInfo.getOutput();
            } else {
                msgInfo = opInfo.getInput();
            }
            Class wrapperTypeClass = msgInfo.getMessageParts().get(0).getTypeClass();
            opInfo = opInfo.getUnwrappedOperation();
            if (isOutput) {
                msgInfo = opInfo.getOutput();
            } else {
                msgInfo = opInfo.getInput();
            }
            List objs = message.getContent(List.class);
            if (objs != null) {
                Object wrapperType = wrapperTypeClass.newInstance();
                int i = 0;
                for (MessagePartInfo p : msgInfo.getMessageParts()) {
                    Object part = objs.get(i);
                    WrapperHelper.setWrappedPart(p.getName().getLocalPart(), wrapperType, part);
                    i++;
                }
                objs = new ArrayList<Object>();
                objs.add(wrapperType);
                message.setContent(List.class, objs);
            }
        }
    }

    /**
     * REVISIT, hack to workaround 2 problems with cxf
     * 1. the message part type class is not set for inner parts w.r.t wrapped doc-style wsdl
     * 2. Since corba binding doesn't depend on wrapped doc-style, there is no need for cxf jaxws
     * WrapperClassIn & WrapperClassOut interceptors.
     */
    protected OperationInfo processWrappedOperation(BindingOperationInfo bopInfo, boolean isOutput)
        throws Exception {
        OperationInfo opInfo = bopInfo.getOperationInfo();
        MessageInfo msgInfo = null;
        if (bopInfo.isUnwrappedCapable()) {
            if (isOutput) {
                msgInfo = opInfo.getOutput();
            } else {
                msgInfo = opInfo.getInput();
            }
            Class wrapperTypeClass = msgInfo.getMessageParts().get(0).getTypeClass();
            opInfo = opInfo.getUnwrappedOperation();
            if (isOutput) {
                msgInfo = opInfo.getOutput();
            } else {
                msgInfo = opInfo.getInput();
            }
           
            for (MessagePartInfo part : msgInfo.getMessageParts()) {
                String elementType = null;
                if (part.isElement()) {
                    elementType = part.getElementQName().getLocalPart();
                } else if (part.getTypeQName() == null) {
                    // handling anonymous complex type
                    elementType = null;
                } else {
                    elementType = part.getTypeQName().getLocalPart();
                }
                part.setTypeClass(getWrappedPartClass(part.getName().getLocalPart(),
                                                      wrapperTypeClass,
                                                      elementType));
            }
        }
        return opInfo;
    }
   
    protected void writeReturnValue(CorbaMessage message,
                                    CorbaMessage outMessage,
                                    OperationInfo opInfo,
                                    ArgType argType,
                                    EventDataReader reader)
        throws Exception {
        Object retValue = null;
       
        if (outMessage.getStreamableReturn() != null) {
            MessageInfo msgInfo = opInfo.getOutput();

            // Handle the parameters that are given for the operation
            XMLInputFactory inputFactory = XMLInputFactory.newInstance();
            XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
            outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES,
                                      Boolean.TRUE);       

            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            XMLEventWriter evtWriter = outputFactory.createXMLEventWriter(outStream);
            CorbaStreamable retVal = outMessage.getStreamableReturn();
            corbaStaxObject.writeObjectToStax(retVal.getObject(), evtWriter,
                                              XMLEventFactory.newInstance());
            evtWriter.flush();
            ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
            XMLEventReader evtReader = inputFactory.createXMLEventReader(inStream);           
            MessagePartInfo part = getReturnMessagePartInfo(msgInfo);
            retValue = reader.read(part, evtReader);
            List<Object> args = new ArrayList<Object>();
            args.add(retValue);
            message.setContent(List.class, args);
        }
    }
   
    protected void addUnmarshalParams(CorbaMessage msg,
                                      CorbaMessage message,
                                      InterfaceInfo info,
                                      OperationType opType,
                                      OperationInfo opInfo,                                 
                                      EventDataReader reader,
                                      boolean isOutput)
        throws Exception {

        MessageInfo msgInfo;
        if (isOutput) {
            msgInfo = opInfo.getOutput();
        } else {
            msgInfo = opInfo.getInput();
        }

        List<ParamType> params = opType.getParam();

        CorbaStreamable[] streamables = msg.getStreamableArguments();      
        List args = message.getContent(List.class);
        if (args == null) {
            args = new ArrayList<Object>();
        }
        int index = 0;
        for (int i = 0; i < params.size(); i++) {
            Object obj = null;
            ParamType param = params.get(i);               
            boolean skipRead = false;
            if (!ContextUtils.isRequestor(msg)) {
                if (param.getMode().equals(ModeType.OUT)) {
                    skipRead = true;
                }
            } else if (param.getMode().equals(ModeType.IN)) {
                skipRead = true;
            }
            if (!skipRead) {
                XMLInputFactory inputFactory = getXMLInputFactory();
                XMLOutputFactory outputFactory = getXMLOutputFactory();
               
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                XMLEventWriter evtWriter = outputFactory.createXMLEventWriter(outStream);
                corbaStaxObject.writeObjectToStax(streamables[i].getObject(),
                                                  evtWriter,
                                                  XMLEventFactory.newInstance());
                evtWriter.flush();
                ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
                XMLEventReader evtReader = inputFactory.createXMLEventReader(inStream);
                MessagePartInfo part = getMessagePartInfo(msgInfo,
                                                          index,
                                                          opType.getReturn() == null,
                                                          isOutput);
                Object partObj = reader.read(part, evtReader);
                args.add(partObj);
                index++;
            } else if (!isOutput) {
                args.add(obj);
            }

        }
        message.setContent(List.class, args);
    }   
   
    protected NVList prepareArguments(CorbaMessage corbaMsg,
                                      CorbaDestination destination,
                                      InterfaceInfo info,
                                      OperationType opType,
                                      QName opQName)
        throws Exception {
       
        BindingInfo bInfo = destination.getBindingInfo();                             
        EndpointInfo eptInfo = destination.getEndPointInfo();
        BindingOperationInfo bOpInfo = bInfo.getOperation(opQName);
        OperationInfo opInfo = bOpInfo.getOperationInfo();       
        Exchange exg = corbaMsg.getExchange();
        exg.put(BindingInfo.class, bInfo);
        exg.put(InterfaceInfo.class, info);
        exg.put(EndpointInfo.class, eptInfo);
        exg.put(EndpointReferenceType.class, destination.getAddress());
        exg.put(ServiceInfo.class, service);
        exg.put(BindingOperationInfo.class, bOpInfo);       
        exg.put(OperationInfo.class, opInfo);
        exg.put(MessageInfo.class, opInfo.getInput());
        exg.put(String.class, opQName.getLocalPart());       
        exg.setInMessage(corbaMsg);

        corbaMsg.put(MessageInfo.class, opInfo.getInput());
                      
        List<ParamType> paramTypes = opType.getParam();      
        CorbaStreamable[] arguments = new CorbaStreamable[paramTypes.size()];                              
        NVList list = prepareDIIArgsList(corbaMsg, arguments, paramTypes, typeMaps);        
       
        return list;
       
    }
   
    protected NVList prepareDIIArgsList(CorbaMessage corbaMsg,
                                        CorbaStreamable[] streamables,
                                        List<ParamType> paramTypes,
                                        List<CorbaTypeMap> maps)
        throws Exception {
       
        // Build the list of DII arguments, returns, and exceptions       
        NVList list = orb.create_list(streamables.length);       
       
        prepareArgs(corbaMsg, paramTypes);
       
        for (int i = 0; i < paramTypes.size(); i++) {          
            ParamType param = paramTypes.get(i);
            QName paramIdlType = param.getIdltype();
            QName paramName = new QName("", param.getName());
            ModeType paramMode = param.getMode();
            CorbaObjectHandler obj =
                CorbaHandlerUtils.initializeObjectHandler(orb, paramName, paramIdlType, maps, service);

            streamables[i] = new CorbaStreamable(obj, paramName);
            if (paramMode.value().equals("in")) {
                streamables[i].setMode(org.omg.CORBA.ARG_IN.value);
            } else if (paramMode.value().equals("out")) {
                streamables[i].setMode(org.omg.CORBA.ARG_OUT.value);
            } else {
                streamables[i].setMode(org.omg.CORBA.ARG_INOUT.value);
            }

            Any value = orb.create_any();
            value.insert_Streamable(streamables[i]);
            list.add_value(streamables[i].getName(), value, streamables[i].getMode());
           
            corbaMsg.addStreamableArgument(streamables[i]);
        }       
        return list;
    }
   
    protected void prepareArgs(CorbaMessage corbaMsg, List<ParamType> paramTypes)
        throws Exception {
        List<Object> args = new ArrayList<Object>();
        int idx = 0;
       
        for (ParamType param : paramTypes) {               
            Class cls = param.getIdltype().getLocalPart().getClass();
            if (cls.isAssignableFrom(Holder.class)) {
                args.add(cls.newInstance());
            }
            idx++;
        }
        corbaMsg.setContent(List.class, args);       
    }
   
    protected XMLOutputFactory getXMLOutputFactory() {
        if (xof == null) {
            xof = XMLOutputFactory.newInstance();
            xof.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
        }
        return xof;
    }

    protected XMLInputFactory getXMLInputFactory() {
        if (xif == null) {
            xif = XMLInputFactory.newInstance();           
        }
        return xif;
    }       

    protected MessagePartInfo getMessagePartInfo(MessageInfo msgInfo,
                                                 int index,
                                                 boolean isVoidReturn,
                                                 boolean isOutput) {
        List<MessagePartInfo> parts = msgInfo.getMessageParts();
        if (isOutput && !isVoidReturn) {
            index++;
        }
        MessagePartInfo part = parts.get(index);
        return part;    
    }

    protected MessagePartInfo getReturnMessagePartInfo(MessageInfo msgInfo) {
        List<MessagePartInfo> parts = msgInfo.getMessageParts();
        MessagePartInfo part = parts.get(0);
        return part;    
    }

    public static Class getWrappedPartClass(String partName, Class wrapperType, String elementType)
        throws Exception {

        String accessor = JAXBUtils.nameToIdentifier(partName, JAXBUtils.IdentifierType.GETTER);

        if (elementType != null && "boolean".equals(elementType.toLowerCase())) {
            // JAXB Exception to get the Boolean property
            accessor = accessor.replaceFirst("get", "is");
        }

        for (Method method : wrapperType.getMethods()) {
            if (method.getParameterTypes().length == 0 && accessor.equals(method.getName())) {

                return method.getReturnType();
            }
        }
        return null;
    }
}
TOP

Related Classes of org.apache.yoko.bindings.corba.interceptors.CorbaInInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.