Package org.apache.yoko.bindings.corba

Source Code of org.apache.yoko.bindings.corba.CorbaStaxObject

/**
* 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;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.cxf.wsdl11.WSDLServiceBuilder;

import org.apache.schemas.yoko.bindings.corba.Anonarray;
import org.apache.schemas.yoko.bindings.corba.Anonsequence;
import org.apache.schemas.yoko.bindings.corba.Array;
import org.apache.schemas.yoko.bindings.corba.CaseType;
import org.apache.schemas.yoko.bindings.corba.Enum;
import org.apache.schemas.yoko.bindings.corba.Exception;
import org.apache.schemas.yoko.bindings.corba.MemberType;
import org.apache.schemas.yoko.bindings.corba.Sequence;
import org.apache.schemas.yoko.bindings.corba.Struct;
import org.apache.schemas.yoko.bindings.corba.Union;
import org.apache.schemas.yoko.bindings.corba.Unionbranch;

import org.apache.ws.commons.schema.XmlSchemaAttribute;
import org.apache.ws.commons.schema.XmlSchemaChoice;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaGroupBase;
import org.apache.ws.commons.schema.XmlSchemaGroupRef;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.apache.ws.commons.schema.XmlSchemaType;

import org.apache.yoko.bindings.corba.interceptors.CorbaOutInterceptor;
import org.apache.yoko.bindings.corba.types.CorbaAnyHandler;
import org.apache.yoko.bindings.corba.types.CorbaArrayHandler;
import org.apache.yoko.bindings.corba.types.CorbaEnumHandler;
import org.apache.yoko.bindings.corba.types.CorbaExceptionHandler;
import org.apache.yoko.bindings.corba.types.CorbaFixedHandler;
import org.apache.yoko.bindings.corba.types.CorbaHandlerUtils;
import org.apache.yoko.bindings.corba.types.CorbaObjectHandler;
import org.apache.yoko.bindings.corba.types.CorbaObjectReferenceHandler;
import org.apache.yoko.bindings.corba.types.CorbaPrimitiveHandler;
import org.apache.yoko.bindings.corba.types.CorbaSequenceHandler;
import org.apache.yoko.bindings.corba.types.CorbaStructHandler;
import org.apache.yoko.bindings.corba.types.CorbaUnionHandler;
import org.apache.yoko.wsdl.CorbaConstants;
import org.apache.yoko.wsdl.CorbaTypeImpl;
import org.apache.yoko.wsdl.W3CConstants;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;

/**
* Holder for reading and writing stax methods.
*/
public class CorbaStaxObject {

    private static final Logger LOG = LogUtils.getL7dLogger(CorbaOutInterceptor.class);

    private static final String XSI_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema-instance";
    private static final String XSI_PREFIX = "xsi";
    private static final String XMLSCHEMA_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema";
    private static final String XMLSCHEMA_PREFIX = "xs";
    private static final String WSDLI_NAMESPACE_URI = "http://www.w3.org/2006/01/wsdl-instance";

    private ORB orb;
    private List<CorbaTypeMap> typeMaps;      
    private ServiceInfo serviceInfo;
   
    public CorbaStaxObject() {        
    }
   
    public CorbaStaxObject(ORB mOrb) {
        orb = mOrb;
    }
   
    public ORB getOrb() {
        return orb;
    }

    public void setOrb(ORB tOrb) {
        orb = tOrb;
    }

    public void setTypeMaps(List<CorbaTypeMap> tMaps) {
        typeMaps = tMaps;
    }
   
    public List<CorbaTypeMap> getTypeMaps() {
        return typeMaps;
    }

    public void setServiceInfo(ServiceInfo info) {
        serviceInfo = info;
    }
   
    public ServiceInfo getServiceInfo() {
        return serviceInfo;
    }

    public CorbaObjectHandler readObjectFromStax(XMLEventReader reader,
                                                 QName idlType)
        throws CorbaBindingException {
        // Find the first start element in the reader. This should be the
        // beginning of our object
        try {
            while (reader.peek().getEventType() != XMLStreamConstants.START_ELEMENT) {
                reader.nextEvent();
            }
        } catch (XMLStreamException ex) {
            throw new CorbaBindingException("Unable to locate start of object", ex);
        }
        CorbaTypeImpl type = CorbaUtils.getCorbaType(idlType, typeMaps);
        XmlSchemaType schemaType = null;
        if (type != null) {
            schemaType = CorbaUtils.getXmlSchemaType(serviceInfo, type.getType());
        }
        return readObjectFromStax(reader, idlType, schemaType, false);
    }

    protected CorbaObjectHandler readObjectFromStax(XMLEventReader reader,
                                                    QName idlType,
                                                    XmlSchemaObject schemaType,
                                                    boolean isNested)
        throws CorbaBindingException {
        TypeCode tc = CorbaUtils.getTypeCode(orb, idlType, typeMaps);
        CorbaObjectHandler obj = null;
        if (CorbaUtils.isPrimitiveIdlType(idlType)) {
            LOG.log(Level.INFO, "Reading primitive type from XML reader");
            obj = readPrimitiveFromStax(reader, idlType, tc, schemaType);
        } else {
            switch (tc.kind().value()) {
            case TCKind._tk_any:
                LOG.log(Level.INFO, "Reading any type from XML reader");
                obj = readAnyFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_array:
                LOG.log(Level.INFO, "Reading array type from XML reader");
                obj = readArrayFromStax(reader, idlType, tc, schemaType, !isNested);
                break;
            case TCKind._tk_enum:
                LOG.log(Level.INFO, "Reading enumeration type from XML reader");
                obj = readEnumFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_except:
                LOG.log(Level.INFO, "Reading exception type from XML reader");
                obj = readExceptionFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_fixed:
                LOG.log(Level.INFO, "Reading fixed type from XML reader");
                obj = readFixedFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_sequence:
                LOG.log(Level.INFO, "Reading sequence type from XML reader");
                obj = readSequenceFromStax(reader, idlType, tc, schemaType, !isNested);
                break;
            case TCKind._tk_string:
            case TCKind._tk_wstring:
                // These will be the case if we have anonymous strings
                LOG.log(Level.INFO, "Reading anonymous string from XML reader");
                obj = readAnonStringsFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_struct:
                LOG.log(Level.INFO, "Reading struct type from XML reader");
                obj = readStructFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_union:
                LOG.log(Level.INFO, "Reading union type from XML reader");
                obj = readUnionFromStax(reader, idlType, tc, schemaType);
                break;
            case TCKind._tk_objref:
                LOG.log(Level.INFO, "Reading object reference from XML reader");
                obj = readObjectReferenceFromStax(reader, idlType, tc, schemaType);
                break;
            default:
                throw new CorbaBindingException("Unsupported complex type");
            }
        }

        return obj;
    }

    public void writeObjectToStax(CorbaObjectHandler obj,
                                  XMLEventWriter writer,
                                  XMLEventFactory factory) {
        XmlSchemaType schemaType = null;
        if (obj != null && obj.getType() != null) {
            CorbaTypeImpl type = obj.getType();
            schemaType = CorbaUtils.getXmlSchemaType(serviceInfo, type.getType());
        }
        writeObjectToStax(obj, schemaType, writer, factory, false);
    }
   
    protected void writeObjectToStax(CorbaObjectHandler obj,
                                     XmlSchemaObject schemaType,
                                     XMLEventWriter writer,
                                     XMLEventFactory factory,
                                     boolean isNested) {
        writeObjectToStax(obj, null, schemaType, writer, factory, isNested);
    }

    protected void writeObjectToStax(CorbaObjectHandler obj,
                                     QName objName,
                                     XmlSchemaObject schemaType,
                                     XMLEventWriter writer,
                                     XMLEventFactory factory,
                                     boolean isNested) {
        try {
            if (obj != null) {
                TypeCode tc = obj.getTypeCode();
                if (CorbaUtils.isPrimitiveIdlType(obj.getIdlType())) {
                    writePrimitiveToStax(obj, objName, schemaType, writer, factory);
                } else {
                    switch (tc.kind().value()) {
                    case TCKind._tk_any:
                        LOG.log(Level.INFO, "Writing any type to XML writer");
                        writeAnyToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_array:
                        LOG.log(Level.INFO, "Writing array type to XML writer");
                        writeArrayToStax(obj, objName, schemaType, writer, factory, !isNested);
                        break;
                    case TCKind._tk_enum:
                        LOG.log(Level.INFO, "Writing enum type to XML writer");
                        writeEnumToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_except:
                        LOG.log(Level.INFO, "Writing exception type to XML writer");
                        writeExceptionToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_fixed:
                        LOG.log(Level.INFO, "Writing fixed type to XML writer");
                        writeFixedToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_sequence:
                        LOG.log(Level.INFO, "Writing sequence type to XML writer");
                        writeSequenceToStax(obj, objName, schemaType, writer, factory, !isNested);
                        break;
                    case TCKind._tk_struct:
                        LOG.log(Level.INFO, "Writing struct type to XML writer");
                        writeStructToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_union:
                        LOG.log(Level.INFO, "Writing union type to XML writer");
                        writeUnionToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_string:
                    case TCKind._tk_wstring:
                        LOG.log(Level.INFO, "Wrting anonymous string to XML writer");
                        writePrimitiveToStax(obj, objName, schemaType, writer, factory);
                        break;
                    case TCKind._tk_objref:
                        LOG.log(Level.INFO, "Writing object reference to XML writer");
                        writeObjectReferenceToStax(obj, objName, schemaType, writer, factory);
                        break;
                    default:
                        throw new CorbaBindingException("Unsupported complex type");
                    }                   
                }
            }
        } catch (XMLStreamException ex) {
            LOG.log(Level.SEVERE, "STAX exception while writing to STAX event writer: " + ex.toString());
            LOG.log(Level.SEVERE, "Object being written: " + obj);
            throw new CorbaBindingException("writeObjectToStax STAX exception", ex);
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            LOG.log(Level.SEVERE, "Non-STAX exception while writing to STAX event writer: " + ex.toString());
            LOG.log(Level.SEVERE, "Object being written: " + obj);
            throw new CorbaBindingException("writeObjectToStax exception", ex);
        }
    }

    protected CorbaObjectHandler readPrimitiveFromStax(XMLEventReader reader,
                                                       QName idlType,
                                                       TypeCode tc,
                                                       XmlSchemaObject schemaType)
        throws CorbaBindingException {
        try {
            StartElement startEl = reader.nextEvent().asStartElement();
            QName name = startEl.getName();
            XMLEvent evt = reader.nextEvent();
            Characters charEl;
            if (evt.isStartElement()) {
                charEl = reader.nextEvent().asCharacters();
            } else {
                charEl = evt.asCharacters();
            }
            String value = charEl.getData();
            reader.nextEvent().asEndElement();
            CorbaPrimitiveHandler obj = new CorbaPrimitiveHandler(name, idlType, tc, null);
            obj.setValueFromData(value);
            return obj;
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Error: Object not correctly defined in the XML reader");
            throw new CorbaBindingException("Invalid XML event read", ex);
        }
    }
   
    protected void writePrimitiveToStax(CorbaObjectHandler obj,
                                        QName objName,
                                        XmlSchemaObject schemaType,
                                        XMLEventWriter writer,
                                        XMLEventFactory factory)
        throws XMLStreamException {
        if (objName == null) {
            objName = obj.getName();
        }
        String value = ((CorbaPrimitiveHandler)obj).getDataFromValue();
        LOG.log(Level.INFO, "Writing primitive type to XML writer");
        StartElement startEl = factory.createStartElement(objName, null, null);
        writer.add(startEl);

        Characters charEvt = factory.createCharacters(value);
        writer.add(charEvt);

        EndElement endEl = factory.createEndElement(objName, null);
        writer.add(endEl);
    }

    //REVISIT, change this to read more than just primitive objects.
    protected CorbaObjectHandler readAnyFromStax(XMLEventReader reader,
                                                 QName idlType,
                                                 TypeCode tc,
                                                 XmlSchemaObject schemaType)
        throws CorbaBindingException {
        try {
            StartElement startEl = reader.nextEvent().asStartElement();
            Iterator attrIter = startEl.getAttributes();
            String anySchemaType = null;
            while (attrIter.hasNext()) {
                Attribute attr = (Attribute)attrIter.next();
                QName attrName = attr.getName();
                if (attrName.getNamespaceURI().equals(XSI_NAMESPACE_URI)
                    && attrName.getLocalPart().equals("type")) {
                    anySchemaType = attr.getValue();
                    break;
                }
            }
            Characters charEl = null;
            XMLEvent event = reader.nextEvent();
            if (event.isStartElement()) {
                startEl = event.asStartElement();
                charEl = reader.nextEvent().asCharacters();               
            } else {
                charEl = event.asCharacters();
            }                                   
                                   
            reader.nextEvent().asEndElement();
            CorbaAnyHandler obj = new CorbaAnyHandler(startEl.getName(), idlType, tc, null);
            obj.setValueFromData(orb, charEl.getData(), anySchemaType);
            return obj;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            LOG.log(Level.SEVERE, "Error: Object not correctly defined in the XML reader");
            throw new CorbaBindingException("Invalid XML event read", ex);
        }
    }

    //REVISIT, change this to write more than just primitive objects.
    protected void writeAnyToStax(CorbaObjectHandler obj,
                                  QName objName,
                                  XmlSchemaObject schemaObj,
                                  XMLEventWriter writer,
                                  XMLEventFactory factory)
        throws XMLStreamException {
        StartElement startEl;
        if (objName == null) {
            objName = obj.getName();
        }
        // Any is a special case. Create an attribute called
        // xsi:type which identifies the type
        // of object stored in the Any. Also create a 'dummy'
        // attribute to get the XML schema
        // namespace included in the Stax event.
        // createNamespace() doesn't work for some reason.
        // TODO: Revisit this.
        String schemaType = ((CorbaAnyHandler)obj).getSchemaType();
        QName attrName = new QName(XSI_NAMESPACE_URI,
                                   "type", XSI_PREFIX);
        Attribute attr = factory.createAttribute(attrName,
                                                 schemaType);
        QName nsName = new QName(XMLSCHEMA_NAMESPACE_URI,
                                 "namespace", XMLSCHEMA_PREFIX);
        Attribute ns = factory.createAttribute(nsName, "");
        List<Attribute> attributes = new ArrayList<Attribute>();
        attributes.add(attr);
        attributes.add(ns);

        startEl = factory.createStartElement(objName, attributes.iterator(), null);

        writer.add(startEl);

        Characters charEvt = factory.createCharacters(((CorbaAnyHandler)obj).getValueData());
        writer.add(charEvt);

        EndElement endEl = factory.createEndElement(objName, null);
        writer.add(endEl);   
    }

    protected CorbaObjectHandler readAnonStringsFromStax(XMLEventReader reader,
                                                         QName idlType,
                                                         TypeCode tc,
                                                         XmlSchemaObject schemaType) {
        CorbaPrimitiveHandler obj = null;
       
        try {
            StartElement startEl = reader.nextEvent().asStartElement();
            Characters charEl = reader.nextEvent().asCharacters();
            reader.nextEvent().asEndElement();
           
            if (tc.kind().value() == TCKind._tk_string) {
                obj =
                    new CorbaPrimitiveHandler(startEl.getName(), CorbaConstants.NT_CORBA_STRING, tc, null);
            } else {
                obj =
                    new CorbaPrimitiveHandler(startEl.getName(), CorbaConstants.NT_CORBA_WSTRING, tc, null);
            }
            obj.setValueFromData(charEl.getData());
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Error: Object not correctly defined in the XML reader");
            throw new CorbaBindingException("Invalid XML event read", ex);
        }
        return obj;
    }
   
    // Anonymous strings do not need an equivalent write - the primitive handler write is sufficuent.
   
    protected CorbaObjectHandler readArrayFromStax(XMLEventReader reader,
                                                   QName idlType,
                                                   TypeCode tc,
                                                   XmlSchemaObject schemaType,
                                                   boolean isTopLevel)
        throws CorbaBindingException {
        CorbaArrayHandler obj = null;
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + idlType);
        }
        try {
            QName arrayElemType = null;
            long arrayBound = 0;
            CorbaTypeImpl type = CorbaUtils.getCorbaType(idlType, typeMaps);
            // Arrays and anonymous arrays can be handled by the same method
            if (type instanceof Anonarray) {
                Anonarray anonArrayType = (Anonarray)type;
                arrayElemType = anonArrayType.getElemtype();
                arrayBound = anonArrayType.getBound();
            } else {
                Array arrayType = (Array)type;
                arrayElemType = arrayType.getElemtype();
                arrayBound = arrayType.getBound();
            }
            XmlSchemaElement el = CorbaHandlerUtils.getXmlSchemaSequenceElement(schemaType, serviceInfo);

            QName name;
            if (isTopLevel) {
                name = reader.nextEvent().asStartElement().getName();
            } else {
                name = el.getQName();
            }

            obj = new CorbaArrayHandler(name, idlType, tc, type);
            boolean nestedArray = isNestedArray(arrayElemType);
            for (int i = 0; i < arrayBound; ++i) {
                if (nestedArray) {
                    reader.nextEvent().asStartElement();
                }
                CorbaObjectHandler element = readObjectFromStax(reader, arrayElemType, el, true);
                obj.addElement(element);
                if (nestedArray) {
                    reader.nextEvent().asEndElement();
                }
            }
            if (isTopLevel) {
                reader.nextEvent().asEndElement();
            }
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading array corba type", ex);
        }
       
        return obj;
    }

    protected void writeArrayToStax(CorbaObjectHandler obj,
                                    QName objName,
                                    XmlSchemaObject schemaType,
                                    XMLEventWriter writer,
                                    XMLEventFactory factory,
                                    boolean isTopLevel)
        throws XMLStreamException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + obj.getIdlType());
        }
        if (objName == null) {
            objName = obj.getName();
        }
        if (isTopLevel) {
            StartElement startEl = factory.createStartElement(objName, null, null);
            writer.add(startEl);
        }
        CorbaArrayHandler arrayHandler = (CorbaArrayHandler)obj;
        XmlSchemaElement el = CorbaHandlerUtils.getXmlSchemaSequenceElement(schemaType, serviceInfo);
        List<CorbaObjectHandler> elements = arrayHandler.getElements();
        for (Iterator<CorbaObjectHandler> elementsIter = elements.iterator(); elementsIter.hasNext();) {
            CorbaObjectHandler handler = elementsIter.next();
            QName handlerName = handler.getName();
            boolean nestedArray = isNestedArray(handler.getTypeCode());
            if (nestedArray) {              
                StartElement startEl = factory.createStartElement(handlerName, null, null);
                writer.add(startEl);
            }
            writeObjectToStax(handler, el, writer, factory, true);
            if (nestedArray) {
                EndElement endEl = factory.createEndElement(handlerName, null);
                writer.add(endEl);
            }
        }
        if (isTopLevel) {
            EndElement endEl = factory.createEndElement(objName, null);
            writer.add(endEl);
        }
    }
   
    protected CorbaObjectHandler readEnumFromStax(XMLEventReader reader,
                                                  QName idlType,
                                                  TypeCode tc,
                                                  XmlSchemaObject schemaType)
        throws CorbaBindingException {
        CorbaEnumHandler obj = null;
        try {
            Enum enumType = (Enum) CorbaUtils.getCorbaType(idlType, typeMaps);
            StartElement enumStartEl = reader.nextEvent().asStartElement();
            obj = new CorbaEnumHandler(enumStartEl.getName(), idlType, tc, enumType);
            Characters enumCharEl = reader.nextEvent().asCharacters();
            obj.setValue(enumCharEl.getData());
            reader.nextEvent().asEndElement();
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading enum corba type", ex);
        }
       
        return obj;
    }
   
    protected void writeEnumToStax(CorbaObjectHandler obj,
                                   QName objName,
                                   XmlSchemaObject schemaType,
                                   XMLEventWriter writer,
                                   XMLEventFactory factory)
        throws XMLStreamException {
        if (objName == null) {
            objName = obj.getName();
        }
        StartElement startEl = factory.createStartElement(objName, null, null);
        writer.add(startEl);   
        CorbaEnumHandler enumHandler = (CorbaEnumHandler)obj;
        Characters charEvt = factory.createCharacters(enumHandler.getValue());
        writer.add(charEvt);
        EndElement endEl = factory.createEndElement(objName, null);
        writer.add(endEl);
    }

    protected CorbaObjectHandler readExceptionFromStax(XMLEventReader reader,
                                                       QName idlType,
                                                       TypeCode tc,
                                                       XmlSchemaObject schemaType)
        throws CorbaBindingException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + idlType);
        }
        CorbaExceptionHandler obj = null;
        try {
            Exception exType = (Exception) CorbaUtils.getCorbaType(idlType, typeMaps);
            StartElement exStartEl = reader.nextEvent().asStartElement();
            obj = new CorbaExceptionHandler(exStartEl.getName(), idlType, tc, exType);
            XmlSchemaComplexType ctype = (XmlSchemaComplexType) schemaType;
            XmlSchemaGroupBase group = (XmlSchemaGroupBase) ctype.getParticle();
            List<MemberType> exMembers = exType.getMember();
            for (int i = 0; i < exMembers.size(); ++i) {
                CorbaObjectHandler member = readObjectFromStax(reader,
                                                               exMembers.get(i).getIdltype(),
                                                               group.getItems().getItem(i),
                                                               true);
                obj.addMember(member);
            }
            reader.nextEvent().asEndElement();
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading exception corba type", ex);
        }
       
        return obj;
    }

    protected void writeExceptionToStax(CorbaObjectHandler obj,
                                        QName objName,
                                        XmlSchemaObject schemaType,
                                        XMLEventWriter writer,
                                        XMLEventFactory factory)
        throws XMLStreamException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + obj.getIdlType());
        }
        if (objName == null) {
            objName = obj.getName();
        }
        StartElement startEl = factory.createStartElement(objName, null, null);
        writer.add(startEl);
        CorbaExceptionHandler exObj = (CorbaExceptionHandler)obj;
        XmlSchemaComplexType ctype = (XmlSchemaComplexType) schemaType;
        XmlSchemaGroupBase group = (XmlSchemaGroupBase) ctype.getParticle();
        List<CorbaObjectHandler> elements = exObj.getMembers();
        for (int i = 0; i < elements.size(); i++) {
            writeObjectToStax(elements.get(i), group.getItems().getItem(i), writer, factory, true);
        }
        EndElement endEl = factory.createEndElement(objName, null);
        writer.add(endEl);
    }

    protected CorbaObjectHandler readSequenceFromStax(XMLEventReader reader,
                                                      QName idlType,
                                                      TypeCode tc,
                                                      XmlSchemaObject schemaType,
                                                      boolean isTopLevel)
        throws CorbaBindingException {
        //check if it is a sequence of octets
        CorbaTypeImpl type = CorbaUtils.getCorbaType(idlType, typeMaps);
        boolean readOctets = type.getType().equals(W3CConstants.NT_SCHEMA_BASE64)
            || type.getType().equals(W3CConstants.NT_SCHEMA_HBIN);
        if ((schemaType == null) && (!readOctets)) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + idlType);
        }
        CorbaSequenceHandler obj = null;
        try {
            QName seqElementType = null;
            long bound = 0;
            if (type instanceof Anonsequence) {
                Anonsequence anonSeqType = (Anonsequence)type;
                seqElementType = anonSeqType.getElemtype();
                bound = anonSeqType.getBound();
            } else {
                Sequence seqType = (Sequence)type;
                seqElementType = seqType.getElemtype();
                bound = seqType.getBound();
            }

            QName name = null;
            if (schemaType instanceof XmlSchemaElement) {
                name = ((XmlSchemaElement) schemaType).getQName();
            }
            if (isTopLevel) {
                name = reader.nextEvent().asStartElement().getName();
            }
            if (name == null) {
                throw new CorbaBindingException("Couldn't find Schema element for corba:sequence " + idlType);
            }

            obj = new CorbaSequenceHandler(name,
                                           idlType,
                                           tc,
                                           type);
            if (!readOctets) {
                addElementsToSequence(obj, reader, seqElementType, bound, schemaType);
            } else {
                QName valueQName = new QName("value");
                TypeCode valueTC = orb.get_primitive_tc(TCKind.from_int(TCKind._tk_octet));
                CorbaPrimitiveHandler handler = new CorbaPrimitiveHandler(valueQName,
                                                                          seqElementType,
                                                                          valueTC,
                                                                          null);
                obj.setTemplateElement(handler);
                XMLEvent evt = reader.nextEvent();
                Characters charEl = evt.asCharacters();
                String data = charEl.getData();
                byte[] value = data.getBytes();
                for (int i = 0; i < data.length(); i++) {
                    handler = new CorbaPrimitiveHandler(valueQName,
                                                        seqElementType,
                                                        valueTC,
                                                        null);
                    handler.setValue(new Byte(value[i]));
                    obj.addElement(handler);
                }
            }
            if (isTopLevel) {
                reader.nextEvent().asEndElement();
            }
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading sequence corba type", ex);
        }
       
        return obj;
    }
   
    private void addElementsToSequence(CorbaSequenceHandler obj,
                                       XMLEventReader reader,
                                       QName seqElementType,
                                       long bound,
                                       XmlSchemaObject schemaType)
        throws java.lang.Exception {
        XmlSchemaElement el = CorbaHandlerUtils.getXmlSchemaSequenceElement(schemaType, serviceInfo);
        QName name = obj.getName();
        QName elementName = el.getQName();
        if (!CorbaUtils.isElementFormQualified(serviceInfo, name.getNamespaceURI())) {
            elementName = new QName("", elementName.getLocalPart());
        }
        CorbaObjectHandler elementObj =
            CorbaHandlerUtils.initializeObjectHandler(orb,
                                                      elementName,
                                                      seqElementType,
                                                      typeMaps,
                                                      serviceInfo);
        obj.setTemplateElement(elementObj);
        boolean nestedSequence = isNestedSequence(seqElementType);
        if (bound == 0) {
            LOG.log(Level.INFO, "Unbounded sequence found");
            XMLEvent event = reader.peek();
            while (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
                StartElement startEl = (StartElement) event;
                //REVISIT, check if qualified or unqualified
                if (startEl.getName().equals(el.getQName())) {
                    if (nestedSequence) {
                        reader.nextEvent().asStartElement();
                    }
                } else {
                    break;
                }
                CorbaObjectHandler element = readObjectFromStax(reader, seqElementType, el, true);
                if (nestedSequence) {
                    reader.nextEvent().asEndElement();
                }
                obj.addElement(element);
                event = reader.peek();
            }
        } else {
            LOG.log(Level.INFO, "Bounded sequence found");
            for (long i = 0; i < bound; ++i) {
                if (nestedSequence) {
                    reader.nextEvent().asStartElement();
                }
                CorbaObjectHandler element = readObjectFromStax(reader, seqElementType, el, true);
                if (nestedSequence) {
                    reader.nextEvent().asEndElement();
                }
                obj.addElement(element);
            }
        }
    }

    protected void writeSequenceToStax(CorbaObjectHandler obj,
                                       QName name,
                                       XmlSchemaObject schemaType,
                                       XMLEventWriter writer,
                                       XMLEventFactory factory,
                                       boolean isTopLevel)
        throws XMLStreamException {
        CorbaTypeImpl type = obj.getType();
        boolean writeOctets = type.getType().equals(W3CConstants.NT_SCHEMA_BASE64)
            || type.getType().equals(W3CConstants.NT_SCHEMA_HBIN);
        if ((schemaType == null) && (!writeOctets)) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + obj.getIdlType());
        }
        if (name == null) {
            name = obj.getName();
        }
        if (isTopLevel) {
            StartElement startEl = factory.createStartElement(name, null, null);
            writer.add(startEl);
        }
        if (!writeOctets) {
            XmlSchemaElement el = CorbaHandlerUtils.getXmlSchemaSequenceElement(schemaType, serviceInfo);
            CorbaSequenceHandler seqHandler = (CorbaSequenceHandler)obj;
            List<CorbaObjectHandler> elements = seqHandler.getElements();
            for (Iterator<CorbaObjectHandler> elementsIter = elements.iterator(); elementsIter.hasNext();) {
                CorbaObjectHandler handler = elementsIter.next();
                QName objName = handler.getName();
                boolean nestedSequence = isNestedSequence(handler.getTypeCode());
                if (nestedSequence) {
                    StartElement startEl = factory.createStartElement(objName, null, null);
                    writer.add(startEl);
                }
                writeObjectToStax(handler, el, writer, factory, true);
                if (nestedSequence) {
                    EndElement endEl = factory.createEndElement(objName, null);
                    writer.add(endEl);
                }
            }
        } else {
            CorbaSequenceHandler seqHandler = (CorbaSequenceHandler) obj;
            List<CorbaObjectHandler> elements = seqHandler.getElements();
            byte[] value = new byte[elements.size()];
            for (int i = 0; i < elements.size(); i++) {
                CorbaPrimitiveHandler handler = (CorbaPrimitiveHandler) elements.get(i);
                value[i] = ((Byte) handler.getValue()).byteValue();
            }
            Characters charEvt = factory.createCharacters(new String(value));
            writer.add(charEvt);
        }
        if (isTopLevel) {
            EndElement endEl = factory.createEndElement(name, null);
            writer.add(endEl);
        }
    }

    protected CorbaObjectHandler readStructFromStax(XMLEventReader reader,
                                                    QName idlType,
                                                    TypeCode tc,
                                                    XmlSchemaObject schemaType)
        throws CorbaBindingException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + idlType);
        }        
        CorbaStructHandler obj = null;
        try {           
            Struct structType = (Struct) CorbaUtils.getCorbaType(idlType, typeMaps);
            XmlSchemaObjectCollection attrs = null;
            XmlSchemaObjectCollection members = null;
           
            boolean readElement = false;

            XmlSchemaObject stype = schemaType;
            if (schemaType instanceof XmlSchemaElement) {
                XmlSchemaElement el = (XmlSchemaElement) schemaType;
                stype = el.getSchemaType();
                if (stype == null) {
                    stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
                }
                readElement = true;
            }
            if (stype instanceof XmlSchemaComplexType) {
                XmlSchemaComplexType ctype = (XmlSchemaComplexType) stype;
                attrs = ctype.getAttributes();
                stype = ctype.getParticle();
                readElement = true;
            }
            if (stype instanceof XmlSchemaGroupRef) {
                members = ((XmlSchemaGroupRef) stype).getParticle().getItems();
            } else if (stype instanceof XmlSchemaGroupBase) {
                members = ((XmlSchemaGroupBase) stype).getItems();
            }
            QName elName;
            if ((attrs != null) && (attrs.getCount() > 0)) {
                elName = reader.peek().asStartElement().getName();
            } else if (readElement) {
                elName = reader.nextEvent().asStartElement().getName();
            } else {
                elName = CorbaUtils.EMPTY_QNAME;
            }
            obj = new CorbaStructHandler(elName, idlType, tc, structType);

            List<MemberType> structMembers = structType.getMember();
            int attrCount = 0;
            int memberCount = 0;
            for (int i = 0; i < structMembers.size(); ++i) {
                XmlSchemaObject schemaObj;
                if ((attrs != null) && (attrCount < attrs.getCount())) {
                    schemaObj = attrs.getItem(attrCount++);
                } else {
                    schemaObj = members.getItem(memberCount++);
                }
                CorbaObjectHandler member = readObjectFromStax(reader,
                                                               structMembers.get(i).getIdltype(),
                                                               schemaObj,
                                                               true);
                obj.addMember(member);
                if ((attrs != null) && (attrs.getCount() != 0) && (attrCount == attrs.getCount())) {
                    //Finished reading all the attributes, now read the start element
                    reader.nextEvent();
                    attrCount++;
                }
            }
            if (readElement) {
                reader.nextEvent().asEndElement();
            }
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading struct corba type", ex);
        }
       
        return obj;
    }

    protected void writeStructToStax(CorbaObjectHandler obj,
                                     QName objName,
                                     XmlSchemaObject schemaType,
                                     XMLEventWriter writer,
                                     XMLEventFactory factory)
        throws XMLStreamException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + obj.getIdlType());
        }
        if (objName == null) {
            objName = obj.getName();
        }
        XmlSchemaObjectCollection attrs = null;
        XmlSchemaObjectCollection members = null;
           
        boolean writeElement = false;

        XmlSchemaObject stype = schemaType;
        if (schemaType instanceof XmlSchemaElement) {
            XmlSchemaElement el = (XmlSchemaElement) schemaType;
            stype = el.getSchemaType();
            if (stype == null) {
                stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
            }
            writeElement = true;
        }
        if (stype instanceof XmlSchemaComplexType) {
            XmlSchemaComplexType ctype = (XmlSchemaComplexType) stype;
            attrs = ctype.getAttributes();
            stype = ctype.getParticle();
            writeElement = true;
        }
        if (stype instanceof XmlSchemaGroupRef) {
            members = ((XmlSchemaGroupRef) stype).getParticle().getItems();
        } else if (stype instanceof XmlSchemaGroupBase) {
            members = ((XmlSchemaGroupBase) stype).getItems();
        }
       
        if (writeElement) {
            StartElement startEl = factory.createStartElement(objName, null, null);
            writer.add(startEl);
        }
       
        CorbaStructHandler structHandler = (CorbaStructHandler)obj;
        List<CorbaObjectHandler> elements = structHandler.getMembers();
        int attrCount = 0;
        int memberCount = 0;
        for (Iterator<CorbaObjectHandler> elementsIter = elements.iterator(); elementsIter.hasNext();) {
            XmlSchemaObject schemaObj;
            if ((attrs != null) && (attrCount != attrs.getCount())) {
                schemaObj = attrs.getItem(attrCount++);
            } else {
                schemaObj = members.getItem(memberCount++);
            }
            writeObjectToStax(elementsIter.next(), schemaObj, writer, factory, true);
        }
        if (writeElement) {
            EndElement endEl = factory.createEndElement(objName, null);
            writer.add(endEl);
        }
    }


    protected CorbaObjectHandler readUnionFromStax(XMLEventReader reader,
                                                   QName idlType,
                                                   TypeCode tc,
                                                   XmlSchemaObject schemaType)
        throws CorbaBindingException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + idlType);
        }
        XmlSchemaObject stype = schemaType;
        boolean readElement = true;
        QName elName = null;
        if (schemaType instanceof XmlSchemaAttribute) {
            readElement = false;
            elName = ((XmlSchemaAttribute) schemaType).getQName();
        } else if (schemaType instanceof XmlSchemaElement) {
            XmlSchemaElement el = (XmlSchemaElement) schemaType;
            elName = ((XmlSchemaElement) el).getQName();
            if (el.isNillable()) {
                readElement = false;
            }
            stype = el.getSchemaType();
            if (stype == null) {
                stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
            }      
        }
        if (stype instanceof XmlSchemaComplexType) {
            XmlSchemaComplexType ctype = (XmlSchemaComplexType) stype;
            stype = ctype.getParticle();
        }
        CorbaObjectHandler obj = null;
        if (!readElement) {
            obj = readAttributeOrNillableElementFromStax(reader, elName, idlType, tc, stype);
        } else {
            obj = readChoiceFromStax(reader, idlType, tc, stype);
        }
        return obj;
    }
    private CorbaObjectHandler readAttributeOrNillableElementFromStax(XMLEventReader reader,
                                                                      QName name,
                                                                      QName idlType,
                                                                      TypeCode tc,
                                                                      XmlSchemaObject schemaType)
        throws CorbaBindingException {
        Union unionType = (Union) CorbaUtils.getCorbaType(idlType, typeMaps);
        CorbaUnionHandler obj = new CorbaUnionHandler(name, idlType, tc, unionType);
        CorbaPrimitiveHandler discObj =
            new CorbaPrimitiveHandler(new QName("discriminator"),
                                      unionType.getDiscriminator(),
                                      orb.get_primitive_tc(TCKind.from_int(TCKind._tk_boolean)),
                                      null);

        //only one union branch for a attribute / element nillable types.
        List<Unionbranch> branches = unionType.getUnionbranch();
        try {
            XMLEvent evt = reader.peek();
            if (schemaType instanceof XmlSchemaAttribute) {
                CorbaPrimitiveHandler value = getAttributeValue(evt, name, branches.get(0).getIdltype());
                if (value != null) {
                    discObj.setValue(Boolean.TRUE);
                    obj.setValue("value", value);
                    obj.addCase(value);
                } else {
                    discObj.setValue(Boolean.FALSE);
                }
            } else if (!isElementNil(evt, name)) {
                discObj.setValue(Boolean.TRUE);
                CorbaObjectHandler branchObj = readObjectFromStax(reader,
                                                                  branches.get(0).getIdltype(),
                                                                  schemaType,
                                                                  true);
                obj.setValue("value", branchObj);
            } else {
                discObj.setValue(Boolean.FALSE);
                reader.nextEvent().asStartElement();
                reader.nextEvent().asEndElement();
            }
            obj.setDiscriminator(discObj);
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading union corba type", ex);
        }
        return obj;
    }
  
    protected CorbaObjectHandler readChoiceFromStax(XMLEventReader reader,
                                                    QName idlType,
                                                    TypeCode tc,
                                                    XmlSchemaObject schemaType)
        throws CorbaBindingException {
        CorbaUnionHandler obj = null;
        try {
            XmlSchemaChoice choiceType = (XmlSchemaChoice) schemaType;
            Union unionType = (Union) CorbaUtils.getCorbaType(idlType, typeMaps);
            QName elName = reader.nextEvent().asStartElement().getName();
            obj = new CorbaUnionHandler(elName, idlType, tc, unionType);
            // Build the entire union with all branches, etc.  Then read info from the XML Event Reader
            String branchName = null;
            XMLEvent evt = reader.peek();
            if (evt.isStartElement()) {
                StartElement branchElement = evt.asStartElement();
                branchName = branchElement.getName().getLocalPart();
            }
            List<Unionbranch> branches = unionType.getUnionbranch();
            XmlSchemaObjectCollection items = choiceType.getItems();               
            for (int i = 0; i < branches.size(); i++) {
                Unionbranch branch = branches.get(i);
                CorbaObjectHandler branchObj = null;
                if (branch.getName().equals(branchName)) {
                    branchObj = readObjectFromStax(reader, branch.getIdltype(), items.getItem(i), true);
                    // We also need to set the discriminator since this is the branch with the actual
                    // union value
                    CorbaObjectHandler discObj =
                        CorbaHandlerUtils.createTypeHandler(orb,
                                                            new QName("discriminator"),
                                                            unionType.getDiscriminator(),
                                                            typeMaps,
                                                            serviceInfo);
                    obj.setDiscriminator(discObj);
                   
                    // Determine the value of the discriminator. 
                    List<CaseType> branchCases = branch.getCase();
                    String discValue = null;
                    if (branchCases.size() != 0) {
                        // This represents a union case.  Set the discriminator based on the first
                        // label value associated with the branch (since we don't have this information)
                        // from the Stax representation of the Celtix object).
                        CaseType caseLabel = branchCases.get(0);
                        discValue = caseLabel.getLabel();
                    } else {
                        // This represents the default case.
                        discValue = obj.createDefaultDiscriminatorLabel();
                    }
                    obj.setDiscriminatorValueFromData(discValue);
                    obj.setValue(branchName, branchObj);
                } else {
                    XmlSchemaElement el = (XmlSchemaElement) items.getItem(i);
                    QName qname = new QName("", branch.getName());
                    if (CorbaUtils.isElementFormQualified(serviceInfo, el.getQName().getNamespaceURI())) {
                        qname = el.getQName();
                    }
                    // Create an object holder with no value
                    branchObj = CorbaHandlerUtils.createTypeHandler(orb,
                                                                    qname,
                                                                    branch.getIdltype(),
                                                                    typeMaps,
                                                                    serviceInfo);
                }
                obj.addCase(branchObj);
            }
            reader.nextEvent().asEndElement();
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading union corba type", ex);
        }
        return obj;
    }

    protected void writeUnionToStax(CorbaObjectHandler obj,
                                    QName objName,
                                    XmlSchemaObject schemaType,
                                    XMLEventWriter writer,
                                    XMLEventFactory factory)
        throws XMLStreamException {
        if (schemaType == null) {
            throw new CorbaBindingException("Couldn't find xml schema object for : " + obj.getIdlType());
        }
        if (objName == null) {
            objName = obj.getName();
        }
        XmlSchemaObject stype = schemaType;
        boolean writeElement = true;
        QName elName = null;
        if (schemaType instanceof XmlSchemaAttribute) {
            writeElement = false;
        } else if (schemaType instanceof XmlSchemaElement) {
            XmlSchemaElement el = (XmlSchemaElement) schemaType;
            if (el.isNillable()) {
                //should not write the start Element.
                writeElement = false;
            }
            stype = el.getSchemaType();
            if (stype == null) {
                stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
            }
        }
        CorbaUnionHandler unionHandler = (CorbaUnionHandler)obj;
        if (!writeElement) {
            writeAttributeOrNillableElementToStax(unionHandler, stype, objName, writer, factory);
        } else {
            StartElement startEl = factory.createStartElement(objName, null, null);
            writer.add(startEl);
            CorbaObjectHandler unionValue = unionHandler.getValue();
            if (unionValue != null) {
                writeObjectToStax(unionValue, stype, writer, factory, true);
            }
            EndElement endEl = factory.createEndElement(objName, null);
            writer.add(endEl);
        }
    }

    protected void writeAttributeOrNillableElementToStax(CorbaUnionHandler obj,
                                                         XmlSchemaObject schemaType,
                                                         QName name,
                                                         XMLEventWriter writer,
                                                         XMLEventFactory factory)
        throws XMLStreamException {
        CorbaPrimitiveHandler discValue = (CorbaPrimitiveHandler) obj.getDiscriminator();     
        if (((Boolean) discValue.getValue()).booleanValue()) {
            CorbaObjectHandler value = obj.getValue();
            if (schemaType instanceof XmlSchemaAttribute) {
                QName attrName = name;
                if (!CorbaUtils.isAttributeFormQualified(serviceInfo, attrName.getNamespaceURI())) {
                    attrName = new QName("", attrName.getLocalPart());
                }
                Attribute attr = factory.createAttribute(attrName,
                                                         ((CorbaPrimitiveHandler) value).getDataFromValue());
                writer.add(attr);
            } else {
                writeObjectToStax(value, name, schemaType, writer, factory, true);
            }
        } else {
            StartElement startEl = factory.createStartElement(name, null, null);
            writer.add(startEl);
            QName nilAttr = new QName("http://www.w3.org/2001/XMLSchema-instance", "nil");
            Attribute attr = factory.createAttribute(nilAttr, "true");
            writer.add(attr);
            EndElement endEl = factory.createEndElement(name, null);
            writer.add(endEl);
        }
    }
   
    protected CorbaObjectHandler readFixedFromStax(XMLEventReader reader,
                                                   QName idlType,
                                                   TypeCode tc,
                                                   XmlSchemaObject schemaType)
        throws CorbaBindingException {
        CorbaFixedHandler obj = null;
        try {
            CorbaTypeImpl type = CorbaUtils.getCorbaType(idlType, typeMaps);
            StartElement fixedStartEl = reader.nextEvent().asStartElement();
            obj = new CorbaFixedHandler(fixedStartEl.getName(), idlType, tc, type);
            Characters fixedCharEl = reader.nextEvent().asCharacters();
            obj.setValueFromData(fixedCharEl.getData());
            reader.nextEvent().asEndElement();
        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading fixed corba type", ex);
        }
        return obj;
    }
   
    protected void writeFixedToStax(CorbaObjectHandler obj,
                                    QName objName,
                                    XmlSchemaObject schemaType,
                                    XMLEventWriter writer,
                                    XMLEventFactory factory)
        throws XMLStreamException {
        if (objName == null) {
            objName = obj.getName();
        }
        StartElement startEl = factory.createStartElement(objName, null, null);
        writer.add(startEl);
        CorbaFixedHandler fixedHandler = (CorbaFixedHandler)obj;
        Characters charEvt = factory.createCharacters(fixedHandler.getValueData());
        writer.add(charEvt);
        EndElement endEl = factory.createEndElement(objName, null);
        writer.add(endEl);
    }

    protected CorbaObjectHandler readObjectReferenceFromStax(XMLEventReader reader,
                                                             QName idlType,
                                                             TypeCode tc,
                                                             XmlSchemaObject schemaType) {
        CorbaObjectReferenceHandler obj = null;
        try {
            Object objType = (Object)CorbaUtils.getCorbaType(idlType, typeMaps);
            StartElement objStartEl = reader.nextEvent().asStartElement();

            obj = new CorbaObjectReferenceHandler(objStartEl.getName(), idlType, tc, objType);
            while (true) {
                // Try to get the next event as a start element.  We should have a start element
                // directly after the objects start if the object reference is valie.  If it
                // isn't, the generated exception should be caught below.
                StartElement startEl = reader.nextEvent().asStartElement();

                if (startEl.getName().getLocalPart().equals("Metadata")) {
                    while (true) {
                        StartElement metaEl = reader.nextEvent().asStartElement();
                        if (metaEl.getName().getLocalPart().equals("InterfaceName")) {
                            Characters intfChars = reader.nextEvent().asCharacters();
                            // TODO: How do we want to handle this information
                        } else if (metaEl.getName().getLocalPart().equals("ServiceName")) {
                            Characters svcChars = reader.nextEvent().asCharacters();
                            // TODO: How do we want to handle this information
                        }
                        reader.nextEvent().asEndElement();
                        if (reader.peek().isEndElement()) {
                            break;
                        }
                    }
                } else if (startEl.getName().getLocalPart().equals("Address")) {
                    Characters addrChars = reader.nextEvent().asCharacters();
                    org.omg.CORBA.Object ref =
                        CorbaObjectReferenceHelper.getReferenceById(addrChars.getData());
                    obj.setReference(ref);
                }

                reader.nextEvent().asEndElement();
                if (reader.peek().isEndElement()) {
                    // Two end elements in a row at this point should mean we've hit the end
                    // of the stax description for the object reference
                    break;
                }
            }
            reader.nextEvent().asEndElement();

            // TODO: Verify that the reference has been set for the object

        } catch (java.lang.Exception ex) {
            LOG.log(Level.SEVERE, "Received exception while reading object of type " + idlType);
            throw new CorbaBindingException("Error while reading object reference corba type", ex);
        }

        return obj;
    }
  
    protected void writeObjectReferenceToStax(CorbaObjectHandler obj,
                                              QName objName,
                                              XmlSchemaObject schemaType,
                                              XMLEventWriter writer,
                                              XMLEventFactory factory)
        throws XMLStreamException {

        CorbaObjectReferenceHandler objRefHandler = (CorbaObjectReferenceHandler)obj;
        org.omg.CORBA.Object corbaObject = objRefHandler.getReference();
       
        // Register the servant if not already done.
        String objAddress = orb.object_to_string(corbaObject);
        org.omg.CORBA.Object servant = CorbaObjectReferenceHelper.getReferenceById(objAddress);
        if (servant == null) {
            CorbaObjectReferenceHelper.addReference(objAddress, corbaObject);
        }
       
        // We need to access the WSDL to find the information to build the metadata for the
        // endpoint reference type we are about to create.
        org.apache.schemas.yoko.bindings.corba.Object refObject =
            (org.apache.schemas.yoko.bindings.corba.Object)objRefHandler.getType();
        Definition wsdlDef = (Definition)serviceInfo.getProperty(WSDLServiceBuilder.WSDL_DEFINITION);
        QName bindingName = refObject.getBinding();
        Binding wsdlBinding = null;
        if (bindingName != null) {
            wsdlBinding = wsdlDef.getBinding(bindingName);
        } else {
            // TODO: Revisit: We are doing this for default object references to obtain the binding
            // that defines the object.  Is this the correct thing to do or do we not even try to
            // find a binding since the information is not provided by the typemapping object?
            wsdlBinding = CorbaObjectReferenceHelper.getDefaultBinding(corbaObject, wsdlDef);
        }

        QName interfaceName = null;
        QName referenceName = null;
        if (wsdlBinding != null) {
            interfaceName = wsdlBinding.getPortType().getQName();
            referenceName = new QName(interfaceName.getLocalPart() + "Ref");
        } else {
            referenceName = new QName("CORBA.Object");
        }
       
        StartElement refStart = factory.createStartElement(referenceName, null, null);
        writer.add(refStart);

        // Add the Address information
        QName addrQName = new QName(CorbaObjectReferenceHelper.ADDRESSING_NAMESPACE_URI, "Address");
        writer.add(factory.createStartElement(addrQName, null, null));
        writer.add(factory.createCharacters(objAddress));
        writer.add(factory.createEndElement(addrQName, null));

        if (wsdlBinding != null) {
            String refNSPrefix = "objrefns";
           
            // Add the Metadata information
            QName metaQName = new QName(CorbaObjectReferenceHelper.ADDRESSING_NAMESPACE_URI, "Metadata");
            List<Attribute> metaAttrs = new ArrayList<Attribute>();
            metaAttrs.add(factory.createAttribute(new QName(WSDLI_NAMESPACE_URI, "wsdlLocation"),
                                                  CorbaObjectReferenceHelper.getWSDLLocation(wsdlDef)));
            writer.add(factory.createStartElement(metaQName, metaAttrs.iterator(), null));

            // Add ServiceName information to Metadata
            QName serviceQName = new QName(CorbaObjectReferenceHelper.ADDRESSING_WSDL_NAMESPACE_URI,
                                           "ServiceName");
            List<Attribute> serviceAttrs = new ArrayList<Attribute>();
            serviceAttrs.add(factory.createAttribute(new QName("EndpointName"),
                                                     CorbaObjectReferenceHelper.getEndpointName(wsdlBinding,
                                                                                                wsdlDef)));
            QName service = CorbaObjectReferenceHelper.getServiceName(wsdlBinding, wsdlDef);
            QName serviceNS = new QName(service.getNamespaceURI(), refNSPrefix, refNSPrefix);
            serviceAttrs.add(factory.createAttribute(serviceNS, ""));
            writer.add(factory.createStartElement(serviceQName, serviceAttrs.iterator(), null));
            writer.add(factory.createCharacters(refNSPrefix + ":" + service.getLocalPart()));
            writer.add(factory.createEndElement(serviceQName, null));

            // Add InterfaceName information to Metadata
            QName interfaceQName = new QName(CorbaObjectReferenceHelper.ADDRESSING_WSDL_NAMESPACE_URI,
                                             "InterfaceName");
            List<Attribute> interfaceAttrs = new ArrayList<Attribute>();
            QName interfaceNS = new QName(interfaceName.getNamespaceURI(), refNSPrefix, refNSPrefix);
            interfaceAttrs.add(factory.createAttribute(interfaceNS, ""));
            writer.add(factory.createStartElement(interfaceQName, interfaceAttrs.iterator(), null));
            writer.add(factory.createCharacters(refNSPrefix + ":" + interfaceName.getLocalPart()));
            writer.add(factory.createEndElement(interfaceQName, null));

            writer.add(factory.createEndElement(metaQName, null));
        }
        writer.add(factory.createEndElement(referenceName, null));
    }
   
    private boolean isNestedSequence(TypeCode tc) {
        boolean result = false;
        if (tc.kind().value() == TCKind._tk_sequence) {
            result = true;
        }
        return result;
    }

    private boolean isNestedSequence(QName seqElType) {
        TypeCode tc = CorbaUtils.getTypeCode(orb, seqElType, typeMaps);
        return isNestedSequence(tc);
    }

    private boolean isNestedArray(TypeCode tc) {
        boolean result = false;
        if (tc.kind().value() == TCKind._tk_array) {
            result = true;
        }
        return result;
    }

    private boolean isNestedArray(QName arrayElType) {
        TypeCode tc = CorbaUtils.getTypeCode(orb, arrayElType, typeMaps);
        return isNestedArray(tc);
    }   

    private boolean isElementNil(XMLEvent evt, QName elName) {
        boolean result = true;
        if (evt.isStartElement()) {
            StartElement el = (StartElement) evt;
            QName name = elName;
            if (!CorbaUtils.isElementFormQualified(serviceInfo, elName.getNamespaceURI())) {
                name = new QName("", elName.getLocalPart());
            }
            if (el.getName().equals(name)) {
                QName nilAttr = new QName("http://www.w3.org/2001/XMLSchema-instance", "nil");
                Attribute attr = el.getAttributeByName(nilAttr);
                if (attr == null) {                
                    result = false;
                } else if (!attr.getValue().equalsIgnoreCase("true")) {
                    result = false;
                }
            }
        } else {
            throw new CorbaBindingException("Expected a element with nillable attribute: " + elName);
        }
        return result;
    }

    private CorbaPrimitiveHandler getAttributeValue(XMLEvent evt, QName attrName, QName idlType) {
        CorbaPrimitiveHandler result = null;
        if (evt.isStartElement()) {
            StartElement el = (StartElement) evt;
            QName name = attrName;
            if (!CorbaUtils.isAttributeFormQualified(serviceInfo, attrName.getNamespaceURI())) {
                name = new QName("", attrName.getLocalPart());
            }
            Attribute attr = el.getAttributeByName(name);
            if (attr != null) {
                TypeCode tc = CorbaUtils.getTypeCode(orb, idlType, typeMaps);
                result = new CorbaPrimitiveHandler(new QName("value"), idlType, tc, null);
                result.setValueFromData(attr.getValue());
            }
        }
        return result;
    }
}
TOP

Related Classes of org.apache.yoko.bindings.corba.CorbaStaxObject

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.