Package org.apache.yoko.tools.processors.idl

Source Code of org.apache.yoko.tools.processors.idl.OperationVisitor

/**
* 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.tools.processors.idl;

import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.PortType;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.xml.namespace.QName;

import antlr.collections.AST;

import org.apache.schemas.yoko.bindings.corba.ArgType;
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.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaType;

import org.apache.yoko.wsdl.CorbaConstants;
import org.apache.yoko.wsdl.CorbaTypeImpl;

public class OperationVisitor extends VisitorBase {

    private static final String REQUEST_SUFFIX = "Request";
    private static final String RESPONSE_SUFFIX = "Response";
   
    private static final String IN_PARAMETER = "inparameter";
    private static final String OUT_PARAMETER = "outparameter";
    private static final String INOUT_PARAMETER = "inoutparameter";
    private static final String RETURN_PARAMETER = "return";
   
    private Definition definition;
    private ExtensionRegistry extReg;
    private PortType portType;
    private Binding binding;
   
    private Message inputMsg;
    private Message outputMsg;
   
    private Part inputPart;
    private Part outputPart;
   
    private OperationType corbaOperation;
   
    public OperationVisitor(Scope scope,
                            XmlSchemaCollection xmlSchemas,
                            XmlSchema xmlSchema,
                            TypeMappingType typeMapRef,
                            Definition wsdlDefinition,
                            PortType wsdlPortType,
                            Binding wsdlBinding) {
        super(scope, xmlSchemas, xmlSchema, typeMapRef);
        definition = wsdlDefinition;
        extReg = definition.getExtensionRegistry();
        portType = wsdlPortType;
        binding = wsdlBinding;
    }
   
    public static boolean accept(Scope scope, XmlSchemaCollection schemas, XmlSchema schema,
                                 TypeMappingType typeMap, AST node) {
        boolean result = false;
        AST node2 = node.getFirstChild();
        if (node2.getType() == IDLTokenTypes.LITERAL_oneway) {
            result = true;
        } else {
            int type = node2.getType();
            result =
                type == IDLTokenTypes.LITERAL_void
                || PrimitiveTypesVisitor.accept(node2)
                || StringVisitor.accept(node2)
                || ScopedNameVisitor.accept(scope, schemas, schema, typeMap, node2)
                || ObjectReferenceVisitor.accept(node2);
        }
        return result;
    }
   
    public void visit(AST node) {
        // <op_dcl> ::= [<op_attribute>] <op_type_spec>
        //              <identifier> <parameter_dcls>
        //              [<raises_expr>] [<context_expr>]
        // <op_attribute> ::= "oneway"
        // <op_type_spec> ::= <param_type_spec>
        //                  | "void"
        // <parameter_dcls> ::= "(" <param_dcl> {"," <param_dcl>}* ")"
        //                    | "(" ")"
        // <raises_expr> ::= "raises" "(" <scoped_name> {"," <scoped_name>}* ")"
        // <context_expr> ::= "context" "(" <string_literal> {"," <string_literal>}* ")"
       
       
        Operation operation = generateOperation(node.toString());

        BindingOperation bindingOperation = generateBindingOperation(binding, operation);
       
        XmlSchemaSequence inputWrappingSequence = new XmlSchemaSequence();
        XmlSchemaElement inputElement = generateWrapper(new QName(schema.getTargetNamespace(),
                                                                  operation.getName()),
                                                        inputWrappingSequence);
        inputMsg = generateInputMessage(operation, bindingOperation);
        inputPart = generateInputPart(inputMsg, inputElement);

        // <op_attribute>
        node = node.getFirstChild();
        XmlSchemaSequence outputWrappingSequence = null;
        XmlSchemaElement outputElement = null;
        if (node != null && (node.getType() == IDLTokenTypes.LITERAL_oneway)) {
            // oneway operations map to operations with only input message
            // no outputMsg nor outputPart need be created
            node = node.getNextSibling();
        } else {
            // normal operations map to request-response operations
            // with input and output messages
            outputWrappingSequence = new XmlSchemaSequence();
            outputElement = generateWrapper(new QName(schema.getTargetNamespace(),
                                                      operation.getName() + RESPONSE_SUFFIX),
                                            outputWrappingSequence);
            outputMsg = generateOutputMessage(operation, bindingOperation);
            outputPart = generateOutputPart(outputMsg, outputElement);          
        }
       
        // <op_type_spec>
        visitOpTypeSpec(node, outputWrappingSequence);
       
        // <parameter_dcls>
        node = TypesUtils.getCorbaTypeNameNode(node);
        while (ParamDclVisitor.accept(node)) {

            ParamDclVisitor visitor = new ParamDclVisitor(getScope(),
                                                          schemas,
                                                          schema,
                                                          typeMap,
                                                          inputWrappingSequence,
                                                          outputWrappingSequence,
                                                          corbaOperation);
            // need to provide the wsdl definition so that object references can be
            // constructed correctly
            visitor.setWSDLDefinition(definition);

            visitor.visit(node);

            node = node.getNextSibling();
        }

        // <raises_expr>
        if (node != null
            && node.getType() == IDLTokenTypes.LITERAL_raises) {
            node = node.getFirstChild();
           
            while (node != null) {
//            ScopedNameVisitor visitor = new ScopedNameVisitor(schemas,
//                                                              schema,
//                                                              typeMap);
//            visitor.visit(node);
//            XmlSchemaType schemaType = visitor.getSchemaType();
//            CorbaTypeImpl corbaType = visitor.getCorbaType();

                createFaultMessage(node, operation, bindingOperation);
               
                node = node.getNextSibling();
            }
        }
       
    }

    private Operation generateOperation(String name) {
        Operation op = definition.createOperation();
        op.setName(name);
        op.setUndefined(false);
        portType.addOperation(op);
        return op;
    }
   
    private BindingOperation generateBindingOperation(Binding wsdlBinding, Operation op) {
        BindingOperation bindingOperation = definition.createBindingOperation();
        //OperationType operationType = null;
        try {
            corbaOperation = (OperationType)extReg.createExtension(BindingOperation.class,
                                                                   CorbaConstants.NE_CORBA_OPERATION);
        } catch (WSDLException ex) {
            throw new RuntimeException(ex);
        }
        corbaOperation.setName(op.getName());
        bindingOperation.addExtensibilityElement(corbaOperation);
        bindingOperation.setOperation(op);
        bindingOperation.setName(op.getName());
        binding.addBindingOperation(bindingOperation);
        return bindingOperation;
    }


    public Message generateInputMessage(Operation operation, BindingOperation bindingOperation) {
        Message msg = definition.createMessage();
        msg.setQName(new QName(definition.getTargetNamespace(), operation.getName()));
        msg.setUndefined(false);
       
        String inputName = operation.getName() + REQUEST_SUFFIX;
        Input input = definition.createInput();
        input.setName(inputName);
        input.setMessage(msg);
       
        BindingInput bindingInput = definition.createBindingInput();
        bindingInput.setName(inputName);   
       
        bindingOperation.setBindingInput(bindingInput);
        operation.setInput(input);
       
        definition.addMessage(msg);
       
        return msg;
    }

    public Message generateOutputMessage(Operation operation, BindingOperation bindingOperation) {
        Message msg = definition.createMessage();
        msg.setQName(new QName(definition.getTargetNamespace(),
                               operation.getName() + RESPONSE_SUFFIX));
        msg.setUndefined(false);
       
        String outputName = operation.getName() + RESPONSE_SUFFIX;
        Output output = definition.createOutput();
        output.setName(outputName);
        output.setMessage(msg);
       
        BindingOutput bindingOutput = definition.createBindingOutput();
        bindingOutput.setName(outputName);   
       
        bindingOperation.setBindingOutput(bindingOutput);
        operation.setOutput(output);
       
        definition.addMessage(msg);
       
        return msg;
    }
   
    private Part generateInputPart(Message inputMessage, XmlSchemaElement element) {
        // message - part
        Part part = definition.createPart();
        part.setName(IN_PARAMETER);
        part.setElementName(element.getQName());
        inputMessage.addPart(part);
        return part;       
    }

    private Part generateOutputPart(Message outputMessage, XmlSchemaElement element) {
        // message - part
        Part part = definition.createPart();
        part.setName(OUT_PARAMETER);
        part.setElementName(element.getQName());
        outputMessage.addPart(part);
        return part;
    }
   
    /*-
     * Build the Wrapped Document Style wrapping elements
     * i.e. <xs:element name="...">
     *       <xs:complexType>
     *        <xs:sequence>
     *         ...
     *        </xs:sequence>
     *       </xs:complexType>
     *      </xs:element>
     */
    private XmlSchemaElement generateWrapper(QName el, XmlSchemaSequence wrappingSequence) {
        XmlSchemaComplexType schemaComplexType = new XmlSchemaComplexType(schema);
        schemaComplexType.setParticle(wrappingSequence);
       
        XmlSchemaElement wrappingSchemaElement = new XmlSchemaElement();
        wrappingSchemaElement.setQName(el);
        wrappingSchemaElement.setName(el.getLocalPart());
        wrappingSchemaElement.setSchemaType(schemaComplexType);

        schema.getElements().add(el, wrappingSchemaElement);
        schema.getItems().add(wrappingSchemaElement);
       
        return wrappingSchemaElement;
    }

    private XmlSchemaElement addElement(XmlSchemaSequence schemaSequence,
                                        XmlSchemaType schemaType,
                                        String name,
                                        boolean isObjectReference) {
        XmlSchemaElement element = new XmlSchemaElement();
        element.setName(name);
        // REVISIT: An object reference requires that we use a ref name.  An element type produces
        // a wsdltojava error.
        if (isObjectReference) {
            element.setRefName(schemaType.getQName());
        } else {
            element.setSchemaTypeName(schemaType.getQName());
        }
       
        schemaSequence.getItems().add(element);
       
        return element;
    }
   
    private void visitOpTypeSpec(AST node, XmlSchemaSequence outputWrappingSequence) {
        if (node.getType() == IDLTokenTypes.LITERAL_void) {
            // nothing to do here, move along
            return;
        } else {
            ParamTypeSpecVisitor visitor = new ParamTypeSpecVisitor(getScope(),
                                                                    schemas,
                                                                    schema,
                                                                    typeMap,
                                                                    definition);

            visitor.visit(node);
           
            XmlSchemaType schemaType = visitor.getSchemaType();
            CorbaTypeImpl corbaType = visitor.getCorbaType();
           
            boolean isObjectReference = false;
            if (corbaType instanceof org.apache.schemas.yoko.bindings.corba.Object) {
                isObjectReference = true;
            }
           
            addElement(outputWrappingSequence, schemaType, RETURN_PARAMETER, isObjectReference);
            addCorbaReturn(corbaType, RETURN_PARAMETER);
        }
    }

    private void addCorbaReturn(CorbaTypeImpl corbaType, String partName) {
        ArgType param = new ArgType();
        param.setName(partName);
        param.setIdltype(corbaType.getQName());
        corbaOperation.setReturn(param);
    }

    private void createFaultMessage(AST node,
                                    Operation operation,
                                    BindingOperation bindingOperation) {
        String exceptionName = node.toString();

        // message
        Message faultMsg = definition.createMessage();
        faultMsg.setQName(new QName(definition.getTargetNamespace(), exceptionName));
        faultMsg.setUndefined(false);

        // message - part
        Part part = definition.createPart();
        part.setName("exception");
        // REVISIT: should be reading QName from exception XmlSchemaElement
        // part.setElementName(element.getQName());
        part.setElementName(new QName(definition.getTargetNamespace(), exceptionName));
        faultMsg.addPart(part);

        // porttype - operation - fault
        Fault fault = definition.createFault();
        fault.setMessage(faultMsg);
        fault.setName(faultMsg.getQName().getLocalPart());
        operation.addFault(fault);

        // binding - operation - corba:operation - corba:raises
        RaisesType raisesType = new RaisesType();
        raisesType.setException(new QName(typeMap.getTargetNamespace(),
                                          exceptionName));
        corbaOperation.getRaises().add(raisesType);

        // binding - operation - fault
        BindingFault bindingFault = definition.createBindingFault();
        bindingFault.setName(faultMsg.getQName().getLocalPart());
        bindingOperation.addBindingFault(bindingFault);

        definition.addMessage(faultMsg);
    }
}
TOP

Related Classes of org.apache.yoko.tools.processors.idl.OperationVisitor

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.