endpointinterfacedescriptionimpl.java

来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 1,033 行 · 第 1/4 页

JAVA
1,033
字号
        // of whether they include an @WebMethod annotation.  That annotation may
        // be present to customize the mapping, but is not required (p14)
        Method[] seiMethods = sei.getMethods();
        ArrayList methodList = new ArrayList();
        if (sei != null) {
            for (Method method : seiMethods) {

                if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
                    continue;
                }
                methodList.add(method);
                if (!Modifier.isPublic(method.getModifiers())) {
                    // JSR-181 says methods must be public (p14)
                    // TODO NLS
                    ExceptionFactory.makeWebServiceException("SEI methods must be public");
                }
                // TODO: other validation per JSR-181
            }

        }
        return (Method[])methodList.toArray(new Method[methodList.size()]);
//        return seiMethods;
    }

    /**
     * Update a previously created EndpointInterfaceDescription with information from an annotated
     * SEI.  This should only be necessary when the this was created with WSDL. In this case, the
     * information from the WSDL is augmented based on the annotated SEI.
     *
     * @param sei
     */
    void updateWithSEI(Class sei) {
        if (seiClass != null && seiClass != sei)
            // TODO: It probably is invalid to try reset the SEI; but this isn't the right error processing
            throw new UnsupportedOperationException(
                    "The seiClass is already set; reseting it is not supported");
        else if (seiClass != null && seiClass == sei)
            // We've already done the necessary updates for this SEI
            return;
        else if (sei != null) {
            seiClass = sei;
            // Update (or possibly add) the OperationDescription for each of the methods on the SEI.
            for (Method seiMethod : getSEIMethods(seiClass)) {

                if (getOperation(seiMethod) != null) {
                    // If an OpDesc already exists with this java method set on it, then the OpDesc has already
                    // been updated for this method, so skip it.
                    continue;
                }
                // At this point (for now at least) the operations were created with WSDL previously.
                // If they had been created from an annotated class and no WSDL, then the seiClass would have 
                // already been set so we would have taken other branches in this if test.  (Note this could
                // change once AxisServices can be built from annotations by the ServiceDescription class).
                // Since the operations were created from WSDL, they will not have a java method, which
                // comes from the SEI, set on them yet.
                //
                // Another consideration is that currently Axis2 does not support overloaded WSDL operations.
                // That means there will only be one OperationDesc build from WSDL.  Still another consideration is
                // that the JAXWS async methods which may exist on the SEI will NOT exist in the WSDL.  An example
                // of these methods for the WSDL operation:
                //     String echo(String)
                // optionally generated JAX-WS SEI methods from the tooling; take note of the annotation specifying the 
                // operation name
                //     @WebMethod(operationName="echo" ...)
                //     Response<String> echoStringAsync(String)
                //     @WebMethod(operationName="echo" ...)
                //     Future<?> echoStringAsync(String, AsyncHandler)
                //
                // So given all the above, the code does the following based on the operation QName
                // (which might also be the java method name; see determineOperationQName for details)
                // (1) If an operationDesc does not exist, add it.
                // (2) If an operationDesc does exist but does not have a java method set on it, set it
                // (3) If an operationDesc does exist and has a java method set on it already, add a new one. 
                //
                // TODO: May need to change when Axis2 supports overloaded WSDL operations
                // TODO: May need to change when ServiceDescription can build an AxisService from annotations

                // Get the QName for this java method and then update (or add) the appropriate OperationDescription
                // See comments below for imporant notes about the current implementation.
                // NOTE ON OVERLOADED OPERATIONS
                // Axis2 does NOT currently support overloading WSDL operations.
                QName seiOperationQName =
                        OperationDescriptionImpl.determineOperationQName(seiMethod);
                OperationDescription[] updateOpDesc = getOperation(seiOperationQName);
                if (updateOpDesc == null || updateOpDesc.length == 0) {
                    // This operation wasn't defined in the WSDL.  Note that the JAX-WS async methods
                    // which are defined on the SEI are not defined as operations in the WSDL.
                    // Although they usually specific the same OperationName as the WSDL operation, 
                    // there may be cases where they do not.
                    // TODO: Is this path an error path, or can the async methods specify different operation names than the 
                    //       WSDL operation?
                    OperationDescription operation = new OperationDescriptionImpl(seiMethod, this);
                    addOperation(operation);
                } else {
                    // Currently Axis2 does not support overloaded operations.  That means that even if the WSDL
                    // defined overloaded operations, there would still only be a single AxisOperation, and it
                    // would be the last operation encounterd.
                    // HOWEVER the generated JAX-WS async methods (see above) may (will always?) have the same
                    // operation name and so will come down this path; they need to be added.
                    // TODO: When Axis2 starts supporting overloaded operations, then this logic will need to be changed
                    // TODO: Should we verify that these are the async methods before adding them, and treat it as an error otherwise?

                    // Loop through all the opdescs; if one doesn't currently have a java method set, set it
                    // If all have java methods set, then add a new one.  Assume we'll need to add a new one.
                    boolean addOpDesc = true;
                    for (OperationDescription checkOpDesc : updateOpDesc) {
                        if (checkOpDesc.getSEIMethod() == null) {
                            // TODO: Should this be checking (somehow) that the signature matches?  Probably not an issue until overloaded WSDL ops are supported.
                            
                            //Make sure that this is not one of the 'async' methods associated with
                            //this operation. If it is, let it be created as its own opDesc.
                            if (!DescriptionUtils.isAsync(seiMethod)) {
                                ((OperationDescriptionImpl) checkOpDesc).setSEIMethod(seiMethod);
                                addOpDesc = false;
                                break;
                            }
                        }
                    }
                    if (addOpDesc) {
                        OperationDescription operation =
                                new OperationDescriptionImpl(seiMethod, this);
                        addOperation(operation);
                    }
                }
            }
        }
    }

    /**
     * Return the OperationDescriptions corresponding to a particular Java method name. Note that an
     * array is returned because a method could be overloaded.
     *
     * @param javaMethodName String representing a Java Method Name
     * @return
     */
    // FIXME: This is confusing; some getOperations use the QName from the WSDL or annotation; this one uses the java method name; rename this signature I think; add on that takes a String but does a QName lookup against the WSDL/Annotation
    public OperationDescription[] getOperationForJavaMethod(String javaMethodName) {
        if (DescriptionUtils.isEmpty(javaMethodName)) {
            return null;
        }

        ArrayList<OperationDescription> matchingOperations = new ArrayList<OperationDescription>();
        for (OperationDescription operation : getOperations()) {
            if (javaMethodName.equals(operation.getJavaMethodName())) {
                matchingOperations.add(operation);
            }
        }

        if (matchingOperations.size() == 0)
            return null;
        else
            return matchingOperations.toArray(new OperationDescription[0]);
    }

    /**
     * Return the OperationDesription (only one) corresponding to the OperationName passed in.
     *
     * @param operationName
     * @return
     */
    public OperationDescription getOperation(String operationName) {
        if (DescriptionUtils.isEmpty(operationName)) {
            return null;
        }

        OperationDescription matchingOperation = null;
        for (OperationDescription operation : getOperations()) {
            if (operationName.equals(operation.getOperationName())) {
                matchingOperation = operation;
                break;
            }
        }
        return matchingOperation;
    }

    public OperationDescription[] getOperations() {
        return operationDescriptions.toArray(new OperationDescription[0]);
    }

    EndpointDescriptionImpl getEndpointDescriptionImpl() {
        return (EndpointDescriptionImpl)parentEndpointDescription;
    }

    public EndpointDescription getEndpointDescription() {
        return parentEndpointDescription;
    }

    /**
     * Return an array of Operations given an operation QName.  Note that an array is returned since
     * a WSDL operation may be overloaded per JAX-WS.
     *
     * @param operationQName
     * @return
     */
    public OperationDescription[] getOperation(QName operationQName) {
        OperationDescription[] returnOperations = null;
        if (!DescriptionUtils.isEmpty(operationQName)) {
            ArrayList<OperationDescription> matchingOperations =
                    new ArrayList<OperationDescription>();
            OperationDescription[] allOperations = getOperations();
            for (OperationDescription operation : allOperations) {
                if (operation.getName().getLocalPart().equals(operationQName.getLocalPart())) {
                    matchingOperations.add(operation);
                }
            }
            // Only return an array if there's anything in it
            if (matchingOperations.size() > 0) {
                returnOperations = matchingOperations.toArray(new OperationDescription[0]);
            }
        }
        return returnOperations;
    }

    /* (non-Javadoc)
    * @see org.apache.axis2.jaxws.description.EndpointInterfaceDescription#getDispatchableOperation(QName operationQName)
    */
    public OperationDescription[] getDispatchableOperation(QName operationQName) {
        OperationDescription[] returnOperations = null;
        OperationDescription[] allMatchingOperations = getOperation(operationQName);
        if (allMatchingOperations != null && allMatchingOperations.length > 0) {
            ArrayList<OperationDescription> dispatchableOperations =
                    new ArrayList<OperationDescription>();
            for (OperationDescription operation : allMatchingOperations) {
                if (!operation.isJAXWSAsyncClientMethod()) {
                    dispatchableOperations.add(operation);
                }
            }

            if (dispatchableOperations.size() > 0) {
                returnOperations = dispatchableOperations.toArray(new OperationDescription[0]);
            }
        }
        return returnOperations;
    }
    /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.description.EndpointInterfaceDescription#getDispatchableOperations()
     */
    public OperationDescription[] getDispatchableOperations() {
        OperationDescription[] returnOperations = null;
        OperationDescription[] allMatchingOperations = getOperations();
        if (allMatchingOperations != null && allMatchingOperations.length > 0) {
            ArrayList<OperationDescription> dispatchableOperations = new ArrayList<OperationDescription>();
            for (OperationDescription operation : allMatchingOperations) {
                if (!operation.isJAXWSAsyncClientMethod()) {
                    dispatchableOperations.add(operation);
                }
            }
            
            if (dispatchableOperations.size() > 0) {
                returnOperations = dispatchableOperations.toArray(new OperationDescription[0]);
            }
        }
        return returnOperations;
    }

    /**
     * Return an OperationDescription for the corresponding SEI method.  Note that this ONLY works
     * if the OperationDescriptions were created from introspecting an SEI.  If the were created
     * with a WSDL then use the getOperation(QName) method, which can return > 1 operation.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?