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

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

/**
* 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.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

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

import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.jaxb.io.EventDataWriter;
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.FaultInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.service.model.MessagePartInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.schemas.yoko.bindings.corba.OperationType;
import org.apache.schemas.yoko.bindings.corba.RaisesType;
import org.apache.schemas.yoko.bindings.corba.TypeMappingType;
import org.apache.yoko.bindings.corba.ContextUtils;
import org.apache.yoko.bindings.corba.CorbaBindingException;
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.CorbaObjectHandler;
import org.apache.yoko.wsdl.CorbaConstants;

public class CorbaFaultOutInterceptor extends AbstractPhaseInterceptor<Message> {

    private static final Logger LOG = LogUtils.getL7dLogger(CorbaFaultOutInterceptor.class);
    protected CorbaStaxObject corbaStaxObject;   
   
    public CorbaFaultOutInterceptor() {
        super();
        setPhase(Phase.MARSHAL);
        corbaStaxObject = new CorbaStaxObject();
    }

    public void handleMessage(Message msg) {
        try {
            CorbaMessage message = (CorbaMessage)msg;
            EventDataWriter writer = (EventDataWriter)ContextUtils.getDataWriter(message);

            CorbaDestination destination = null;
            if (message.getDestination() != null) {
                destination = (CorbaDestination)message.getDestination();
            } else {
                destination = (CorbaDestination)message.getExchange().getDestination();
            }

            org.omg.CORBA.ORB orb = (org.omg.CORBA.ORB) message.get(CorbaConstants.ORB);
            if (orb == null) {
                orb = (org.omg.CORBA.ORB) message.getExchange().get(org.omg.CORBA.ORB.class);
            }
            corbaStaxObject.setOrb(orb);

            List<CorbaTypeMap> typeMaps = new ArrayList<CorbaTypeMap>();               
            ServiceInfo 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);
            }

            Throwable ex = message.getContent(Exception.class);
            ex = ex.getCause();
            if (ex instanceof InvocationTargetException) {
                ex = ex.getCause();
            }

            // Get information about the operation being invoked from the WSDL
            // definition.
            // We need this to marshal data correctly

            BindingInfo bInfo = destination.getBindingInfo();
            InterfaceInfo info = bInfo.getInterface();       
       
            String opName = message.getExchange().get(String.class);
               
            Iterator iter = bInfo.getOperations().iterator();

            BindingOperationInfo bopInfo = null;
            OperationType opType = null;          
            while (iter.hasNext()) {
                bopInfo = (BindingOperationInfo)iter.next();
                if (bopInfo.getName().getLocalPart().equals(opName)) {
                    opType = bopInfo.getExtensor(OperationType.class);
                    break;
                }
            }
            if (opType == null) {
                throw new CorbaBindingException("Unable to find operation definition");
            }

            OperationInfo opInfo = bopInfo.getOperationInfo();

            QName exIdlType = null;
            List<RaisesType> exList = opType.getRaises();
            for (Iterator<RaisesType> i = exList.iterator(); i.hasNext();) {
                // REVISIT: Note that this assumes that exception names need to
                // be unique. We should make
                // sure that this is really the case.
                RaisesType raises = i.next();

                if (raises.getException().getLocalPart().equals(ex.getClass().getSimpleName())) {
                    exIdlType = raises.getException();
                    break;
                }
            }

            if (exIdlType != null) {
                setUserException(message, ex, exIdlType, opInfo, writer);
            }

        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "CORBA marshal fault exception", ex);
            throw new CorbaBindingException("Marshal fault failed", ex);
        }

    }

    protected void setUserException(CorbaMessage message,
                                    Throwable ex,
                                    QName exIdlType,
                                    OperationInfo opInfo,
                                    EventDataWriter writer)
        throws Exception {
        QName elName = new QName("", exIdlType.getLocalPart());
        MessagePartInfo faultPart = getFaultMessagePartInfo(opInfo, elName);
        if (faultPart == null) {
            throw new CorbaBindingException("Coulnd't find the message fault part : " + elName);
        }

        Method faultMethod = ex.getClass().getMethod("getFaultInfo");
        if (faultMethod == null) {
            return;
        }
        Object fault = faultMethod.invoke(ex);

        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);
        writer.write(fault, faultPart, evtWriter);
        LOG.log(Level.INFO, "Found exception in the raises list.  Marshalling.");
        ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
        XMLEventReader evtReader = inputFactory.createXMLEventReader(inStream);
        CorbaObjectHandler obj = corbaStaxObject.readObjectFromStax(evtReader, exIdlType);
        CorbaStreamable streamable = new CorbaStreamable(obj, elName);
        message.setStreamableException(streamable);
    }

    protected MessagePartInfo getFaultMessagePartInfo(OperationInfo opInfo, QName faultName) {
        Iterator<FaultInfo> faults = opInfo.getFaults().iterator();
        while (faults.hasNext()) {
            FaultInfo fault = faults.next();
            if (fault.getFaultName().getLocalPart().equals(faultName.getLocalPart())) {
                return fault.getMessageParts().get(0);
            }
        }
        return null;
    }
   
}
TOP

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

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.