/**
   * All methods should have a
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    result = getInitializedResult();
    //        boolean oneFailed = false;

    try {
      if (descriptor instanceof EjbSessionDescriptor || descriptor instanceof EjbEntityDescriptor) {

        Set methods = descriptor.getMethodDescriptors();
        //		 Set methodPermissions = new HashSet();
        boolean noPermissions = false;

        for (Iterator i = methods.iterator(); i.hasNext(); ) {
          MethodDescriptor md = (MethodDescriptor) i.next();
          Set permissions = descriptor.getMethodPermissionsFor(md);
          if (permissions.isEmpty() || (permissions == null)) {
            result.addWarningDetails(
                smh.getLocalString(
                    getClass().getName() + ".failed",
                    "Warning: Method [ {0} ] of EJB [ {1} ] does not have assigned security-permissions",
                    new Object[] {md.getName(), descriptor.getName()}));
            result.setStatus(result.WARNING);
            noPermissions = true;
          }
        }

        if (!noPermissions) {
          result.passed(
              smh.getLocalString(
                  getClass().getName() + ".passed",
                  "Valid: All [ {0} ]EJB  interfaces methods have security-permissions assigned.",
                  new Object[] {descriptor.getName()}));
        }

      } else {
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable",
                "The bean [ {0} ] is neither a Session nor Entity Bean",
                new Object[] {descriptor.getName()}));
        return result;
      }
    } catch (Exception e) {
      result.failed(
          smh.getLocalString(
              getClass().getName() + ".exception",
              "The test generated the following exception [ {0} ]",
              new Object[] {e.getLocalizedMessage()}));
    }
    return result;
  }
Example #2
0
 public Result check(EjbDescriptor descriptor) {
   Result result = getInitializedResult();
   ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();
   boolean oneFailed = false;
   try {
     Set resRef = descriptor.getResourceReferenceDescriptors();
     if (!(resRef.isEmpty())) {
       Iterator it = resRef.iterator();
       while (it.hasNext()) {
         ResourceReferenceDescriptor resDesc = ((ResourceReferenceDescriptor) it.next());
         String refName = resDesc.getName();
         if (refName == null || refName.length() == 0) {
           addErrorDetails(result, compName);
           result.failed(
               smh.getLocalString(
                   getClass().getName() + ".failed",
                   "FAILED [AS-EJB resource-ref] : resource-ref has empty res-ref-name"));
         } else {
           addGoodDetails(result, compName);
           result.passed(
               smh.getLocalString(
                   getClass().getName() + ".passed",
                   "PASSED [AS-EJB resource-ref] : res-ref-name is {0}",
                   new Object[] {refName}));
         }
       }
     } else {
       addNaDetails(result, compName);
       result.notApplicable(
           smh.getLocalString(
               getClass().getName() + ".notApplicable",
               "{0} Does not define any resource-ref Elements",
               new Object[] {descriptor.getName()}));
     }
   } catch (Exception ex) {
     addErrorDetails(result, compName);
     result.addErrorDetails(
         smh.getLocalString(
             getClass().getName() + ".notRun",
             "NOT RUN [AS-EJB] : Could not create the descriptor object"));
   }
   return result;
 }
  private void commonToBothInterfaces(String intf, EjbDescriptor descriptor) {
    try {
      Class intfClass = Class.forName(intf, false, getVerifierContext().getClassLoader());

      for (Method remoteMethod : intfClass.getMethods()) {

        // we don't test the EJB methods
        if (remoteMethod.getDeclaringClass().getName().equals("javax.ejb.EJBObject")) continue;
        Class beanClass =
            Class.forName(
                descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());
        for (Method method : beanClass.getMethods()) {

          if (method.getName().equals(remoteMethod.getName())
              && !RmiIIOPUtils.isValidRmiIIOPReturnType(method.getReturnType())) {
            // The methods arguments types must be legal types for
            // RMI-IIOP.  This means that their return values must
            // be of valid types for RMI-IIOP,
            addErrorDetails(result, compName);
            result.failed(
                smh.getLocalString(
                    getClass().getName() + ".failed",
                    "Error: business method [ {0} ] was found, but "
                        + "business method has invalid return type [ {1} ]. Business "
                        + "method return type must be a valid type for RMI-IIOP.",
                    new Object[] {method.getName(), method.getReturnType()}));
          }
        }
      }

    } catch (ClassNotFoundException e) {
      Verifier.debug(e);
      addErrorDetails(result, compName);
      result.failed(
          smh.getLocalString(
              getClass().getName() + ".failedException",
              "Error: Remote interface [ {0} ] or bean class [ {1} ] does "
                  + "not exist or is not loadable within bean [ {2} ].",
              new Object[] {
                descriptor.getRemoteClassName(), descriptor.getEjbClassName(), descriptor.getName()
              }));
    }
  }
  /**
   * Entity bean's Primary Key Class test. If the enterprise bean is a Entity Bean, the Bean
   * provider specifies the fully qualified name of the Entity bean's primary key class in the
   * "primary-class" element. The Bean provider 'must' specify the primary key class for an Entity
   * with bean managed persistence, and 'may' (but is not required to) specify the primary key class
   * for an Entity with Container-managed persistence.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType();
      if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) {
        logger.log(
            Level.FINE,
            getClass().getName() + ".debug1",
            new Object[] {descriptor.getName(), "bean"});
        String primkey = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName();

        if (!primkey.equals("java.lang.String")) {
          try {
            Class c = Class.forName(primkey, false, getVerifierContext().getClassLoader());

            result.addGoodDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.passed(
                smh.getLocalString(
                    getClass().getName() + ".passed",
                    "Primary Key Class [ {0} ] exist and is loadable",
                    new Object[] {primkey}));
          } catch (Exception e) {
            Verifier.debug(e);
            result.addErrorDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.failed(
                smh.getLocalString(
                    getClass().getName() + ".failedException",
                    "Error: Loading Primary Key Class [ {0} ]",
                    new Object[] {primkey}));
            return result;
          }
        } else {
          result.addGoodDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));

          result.passed(
              smh.getLocalString(
                  getClass().getName() + ".passed1",
                  "Primary Key Class is [ {0} ]",
                  new Object[] {primkey}));
        }

        return result;

      } else if (EjbEntityDescriptor.CONTAINER_PERSISTENCE.equals(persistence)) {
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable1",
                "Entity Bean [ {0} ] with [ {1} ] managed persistence, primkey optional.",
                new Object[] {descriptor.getName(), persistence}));
        return result;
      } else {
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable2",
                "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.",
                new Object[] {
                  EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistence
                }));
        return result;
      }
    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * Entity Bean's ejbCreate(...) methods return test. Each entity Bean class may define zero or
   * more ejbCreate(...) methods. The number and signatures of a entity Bean's create methods are
   * specific to each EJB class. The method signatures must follow these rules:
   *
   * <p>The method name must be ejbCreate.
   *
   * <p>The return type must be primary key type.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType();
      if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) {
        boolean oneFailed = false;
        boolean oneWarning = false;
        int foundAtLeastOne = 0;
        try {
          Context context = getVerifierContext();
          ClassLoader jcl = context.getClassLoader();
          Class c =
              Class.forName(
                  descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());

          String primaryKeyType = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName();
          boolean ejbCreateFound = false;
          boolean returnsPrimaryKeyType = false;
          // start do while loop here....
          do {
            Method[] methods = c.getDeclaredMethods();
            for (int i = 0; i < methods.length; i++) {
              // reset flags from last time thru loop
              ejbCreateFound = false;
              returnsPrimaryKeyType = false;
              // The method name must be ejbCreate.
              if (methods[i].getName().startsWith("ejbCreate")) {
                foundAtLeastOne++;
                ejbCreateFound = true;

                // The return type must be primary key type.
                Class rt = methods[i].getReturnType();
                if (rt.getName().equals(primaryKeyType)) {
                  returnsPrimaryKeyType = true;
                }

                // now display the appropriate results for this particular ejbCreate
                // method
                if (ejbCreateFound && !returnsPrimaryKeyType) {
                  if (primaryKeyType.equals("java.lang.Object")) {
                    oneWarning = true;
                    result.addWarningDetails(
                        smh.getLocalString(
                            "tests.componentNameConstructor",
                            "For [ {0} ]",
                            new Object[] {compName.toString()}));
                    result.addWarningDetails(
                        smh.getLocalString(
                            getClass().getName() + ".debug1",
                            "For EJB Class [ {0} ] method [ {1} ]",
                            new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
                    result.addWarningDetails(
                        smh.getLocalString(
                            getClass().getName() + ".warning",
                            "Warning: An [ {0} ] method was found, but [ {1} ] method has [ {2} ] return type.   Deployment descriptor primary key type [ {3} ]. Definition of the primary key type is deferred to deployment time ?",
                            new Object[] {
                              methods[i].getName(),
                              methods[i].getName(),
                              methods[i].getReturnType().getName(),
                              primaryKeyType
                            }));
                  } else {
                    oneFailed = true;
                    result.addErrorDetails(
                        smh.getLocalString(
                            "tests.componentNameConstructor",
                            "For [ {0} ]",
                            new Object[] {compName.toString()}));
                    result.addErrorDetails(
                        smh.getLocalString(
                            getClass().getName() + ".debug1",
                            "For EJB Class [ {0} ] method [ {1} ]",
                            new Object[] {descriptor.getEjbClassName(), methods[i].getName()}));
                    result.addErrorDetails(
                        smh.getLocalString(
                            getClass().getName() + ".failed",
                            "Error: An [ {0} ] method was found, but [ {1} ] method has illegal return value.   [ {2} ] methods must return primary key type [ {3} ].",
                            new Object[] {
                              methods[i].getName(),
                              methods[i].getName(),
                              methods[i].getName(),
                              primaryKeyType
                            }));
                    break;
                  }
                }
              }
            }
            if (oneFailed == true) break;
          } while (((c = c.getSuperclass()) != null) && (foundAtLeastOne == 0));

          if (foundAtLeastOne == 0) {
            result.addNaDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.notApplicable(
                smh.getLocalString(
                    getClass().getName() + ".notApplicable0",
                    "[ {0} ] does not declare any ejbCreate(...) methods.",
                    new Object[] {descriptor.getEjbClassName()}));
          }
          if (oneFailed == false && foundAtLeastOne > 0) {
            result.addGoodDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.addGoodDetails(
                smh.getLocalString(
                    getClass().getName() + ".debug1",
                    "For EJB Class [ {0} ]",
                    new Object[] {descriptor.getEjbClassName()}));
            result.addGoodDetails(
                smh.getLocalString(
                    getClass().getName() + ".passed",
                    "[ {0} ] properly declares ejbCreate<method> method to return primary key type [ {1} ].",
                    new Object[] {descriptor.getEjbClassName(), primaryKeyType}));
          }
        } catch (ClassNotFoundException e) {
          Verifier.debug(e);
          result.addErrorDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.failed(
              smh.getLocalString(
                  getClass().getName() + ".failedException",
                  "Error: [ {0} ] class not found.",
                  new Object[] {descriptor.getEjbClassName()}));
          oneFailed = true;
        }

        if (oneFailed) {
          result.setStatus(result.FAILED);
        } else if (foundAtLeastOne == 0) {
          result.setStatus(result.NOT_APPLICABLE);
        } else {
          if (oneWarning) {
            result.setStatus(result.WARNING);
          } else {

            result.setStatus(result.PASSED);
          }
        }

        return result;

      } else { // if (CONTAINER_PERSISTENCE.equals(persistence)) {
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable1",
                "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.",
                new Object[] {
                  EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistence
                }));
        return result;
      }

    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * Entity bean's Primary Key Class type test. If the enterprise bean is a Entity Bean, the Bean
   * provider specifies the fully qualified name of the Entity bean's primary key class in the
   * "primary-class" element. The Bean provider 'must' specify the primary key class for an Entity
   * with bean managed persistence, and 'may' (but is not required to) specify the primary key class
   * for an Entity with Container-managed persistence.
   *
   * <p>Special case: Unknown primary key class In special situations, the Bean Provider may choose
   * not to specify the primary key class for an entity bean with container-managed persistence.
   * This case happens if the Bean Provider wants to allow the Deployer to select the primary key
   * fields at deployment time. The Deployer uses instructions supplied by the Bean Provider (these
   * instructions are beyond the scope of the EJB spec.) to define a suitable primary key class.
   *
   * <p>In this special case, the type of the argument of the findByPrimaryKey method must be
   * declared as java.lang.Object, and the return value of ejbCreate() must be declared as
   * java.lang.Object. The Bean Provider must specify the primary key class in the deployment
   * descriptor as of the type java.lang.Object.
   *
   * <p>The primary key class is specified at deployment time when the Bean Provider develops
   * enterprise beans that is intended to be used with multiple back-ends that provide persistence,
   * and when these multiple back-ends require different primary key structures.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType();
      if (EjbEntityDescriptor.CONTAINER_PERSISTENCE.equals(persistence)) {
        String primkey = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName();

        // primkey can be not set, via setting xml element
        // <prim-key-class> to "java.lang.Object"
        if (primkey.equals("java.lang.Object")) {
          result.addGoodDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.passed(
              smh.getLocalString(
                  getClass().getName() + ".passed",
                  "Properly defined primary key class type [ {0} ]",
                  new Object[] {"java.lang.Object"}));
        } else {
          result.addNaDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.notApplicable(
              smh.getLocalString(
                  getClass().getName() + ".notApplicable1",
                  "Primary Key Class is [ {0} ]",
                  new Object[] {primkey}));
        }

        return result;

      } else if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) {
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable2",
                "Entity Bean with [ {0} ] managed persistence, primkey mandatory.",
                new Object[] {persistence}));
        return result;
      } else {
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable3",
                "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.",
                new Object[] {
                  EjbEntityDescriptor.CONTAINER_PERSISTENCE, descriptor.getName(), persistence
                }));
        return result;
      }
    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * Define ejbFindByPrimaryKey method arguments test.
   *
   * <p>Every entity enterprise Bean class must define the ejbFindByPrimaryKey method.
   *
   * <p>The methods arguments types must be legal types for RMI-IIOP.
   *
   * @param descriptor the Enterprise Java Bean deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(EjbDescriptor descriptor) {

    Result result = getInitializedResult();
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    if (descriptor instanceof EjbEntityDescriptor) {
      String persistentType = ((EjbEntityDescriptor) descriptor).getPersistenceType();
      if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistentType)) {
        Class[] ejbFinderMethodParameterTypes;
        boolean ejbFindByPrimaryKeyMethodFound = false;
        boolean oneFailed = false;
        boolean isLegalRMIIIOP = false;
        try {
          // retrieve the EJB Class Methods
          Context context = getVerifierContext();
          ClassLoader jcl = context.getClassLoader();
          Class EJBClass =
              Class.forName(
                  descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader());
          // start do while loop here....
          do {
            Method[] ejbFinderMethods = EJBClass.getDeclaredMethods();

            for (int j = 0; j < ejbFinderMethods.length; ++j) {
              if (ejbFinderMethods[j].getName().equals("ejbFindByPrimaryKey")) {
                // Every entity enterprise Bean class must define the
                // ejbFindByPrimaryKey method.
                ejbFindByPrimaryKeyMethodFound = true;

                // The methods arguments types must be legal types for RMI-IIOP.
                ejbFinderMethodParameterTypes = ejbFinderMethods[j].getParameterTypes();
                if (RmiIIOPUtils.isValidRmiIIOPParameters(ejbFinderMethodParameterTypes)) {
                  // these method parameters are valid, continue
                  isLegalRMIIIOP = true;
                }

                if (ejbFindByPrimaryKeyMethodFound && isLegalRMIIIOP) {
                  result.addGoodDetails(
                      smh.getLocalString(
                          "tests.componentNameConstructor",
                          "For [ {0} ]",
                          new Object[] {compName.toString()}));
                  result.addGoodDetails(
                      smh.getLocalString(
                          getClass().getName() + ".debug1",
                          "For EJB Class [ {0} ] Finder Method [ {1} ]",
                          new Object[] {EJBClass.getName(), ejbFinderMethods[j].getName()}));
                  result.addGoodDetails(
                      smh.getLocalString(
                          getClass().getName() + ".passed",
                          "An [ {0} ] method with valid RMI-IIOP argument types was found.",
                          new Object[] {ejbFinderMethods[j].getName()}));
                } else if (ejbFindByPrimaryKeyMethodFound && (!isLegalRMIIIOP)) {
                  oneFailed = true;
                  result.addErrorDetails(
                      smh.getLocalString(
                          "tests.componentNameConstructor",
                          "For [ {0} ]",
                          new Object[] {compName.toString()}));
                  result.addErrorDetails(
                      smh.getLocalString(
                          getClass().getName() + ".debug1",
                          "For EJB Class [ {0} ] Finder Method [ {1} ]",
                          new Object[] {EJBClass.getName(), ejbFinderMethods[j].getName()}));
                  result.addErrorDetails(
                      smh.getLocalString(
                          getClass().getName() + ".failed",
                          "Error: An [ {0} ] method was found, but [ {1} ] method has illegal parameter values. [ {2} ] methods arguments types must be legal types for RMI-IIOP.",
                          new Object[] {
                            ejbFinderMethods[j].getName(),
                            ejbFinderMethods[j].getName(),
                            ejbFinderMethods[j].getName()
                          }));
                }
                // found one, and there should only be one, break out
                break;
              }
            }
          } while (((EJBClass = EJBClass.getSuperclass()) != null)
              && (!ejbFindByPrimaryKeyMethodFound));

          if (!ejbFindByPrimaryKeyMethodFound) {
            oneFailed = true;
            result.addErrorDetails(
                smh.getLocalString(
                    "tests.componentNameConstructor",
                    "For [ {0} ]",
                    new Object[] {compName.toString()}));
            result.addErrorDetails(
                smh.getLocalString(
                    getClass().getName() + ".debug3",
                    "For EJB Class [ {0} ]",
                    new Object[] {descriptor.getEjbClassName()}));
            result.addErrorDetails(
                smh.getLocalString(
                    getClass().getName() + ".failed1",
                    "Error: No ejbFindByPrimaryKey method was found in bean class."));
          }

        } catch (ClassNotFoundException e) {
          Verifier.debug(e);
          result.addErrorDetails(
              smh.getLocalString(
                  "tests.componentNameConstructor",
                  "For [ {0} ]",
                  new Object[] {compName.toString()}));
          result.failed(
              smh.getLocalString(
                  getClass().getName() + ".failedException",
                  "Error: EJB Class [ {0} ] does not exist or is not loadable.",
                  new Object[] {descriptor.getEjbClassName()}));
          oneFailed = true;
        }

        if (oneFailed) {
          result.setStatus(result.FAILED);
        } else {
          result.setStatus(result.PASSED);
        }
      } else { // (CONTAINER_PERSISTENCE.equals(persistentType))
        result.addNaDetails(
            smh.getLocalString(
                "tests.componentNameConstructor",
                "For [ {0} ]",
                new Object[] {compName.toString()}));
        result.notApplicable(
            smh.getLocalString(
                getClass().getName() + ".notApplicable2",
                "Expected persistence type [ {0} ], but bean [ {1} ] has persistence type [ {2} ]",
                new Object[] {
                  EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistentType
                }));
      }

      return result;

    } else {
      result.addNaDetails(
          smh.getLocalString(
              "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()}));
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "[ {0} ] expected {1} bean, but called with {2} bean.",
              new Object[] {getClass(), "Entity", "Session"}));
      return result;
    }
  }
  /**
   * run an individual home method test
   *
   * @param method the home method to test
   * @param descriptor the deployment descriptor for the entity bean
   * @param result the result object
   */
  protected void runIndividualHomeMethodTest(
      Method method, EjbDescriptor descriptor, Result result) {

    Method m;
    ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor();

    try {
      // retrieve the remote interface methods
      ClassLoader jcl = getVerifierContext().getClassLoader();
      Class ejbClass = Class.forName(descriptor.getEjbClassName(), false, jcl);

      // Bug: 4952890. first character of this name should be converted to UpperCase.
      String methodName =
          method
              .getName()
              .replaceFirst(
                  method.getName().substring(0, 1), method.getName().substring(0, 1).toUpperCase());
      String expectedMethodName = "ejbHome" + methodName;
      do {
        // retrieve the EJB Class Methods
        m = getMethod(ejbClass, expectedMethodName, method.getParameterTypes());
      } while (((ejbClass = ejbClass.getSuperclass()) != null) && (m == null));

      if (m != null) {
        int modifiers = m.getModifiers();
        if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
          addGoodDetails(result, compName);
          result.addGoodDetails(
              smh.getLocalString(
                  getClass().getName() + ".passed",
                  "For method [ {1} ] in Home Interface [ {0} ], ejbHome method is public and not static",
                  new Object[] {method.getDeclaringClass().getName(), method.getName()}));
          result.setStatus(Result.PASSED);
          // return true;
        } else {
          addErrorDetails(result, compName);
          result.addErrorDetails(
              smh.getLocalString(
                  getClass().getName() + ".notApplicable",
                  "Error : For method [ {1} ] defined in Home Interface [ {0} ], the ejbHome method is either static or not public",
                  new Object[] {method.getDeclaringClass().getName(), method.getName()}));
          result.setStatus(Result.FAILED);
          // return false;
        }
      } else {
        addErrorDetails(result, compName);
        result.addErrorDetails(
            smh.getLocalString(
                getClass().getName() + ".failed",
                "Error : For method [ {1} ] defined in Home Interface [ {0} ], no ejbHome name matching method was found",
                new Object[] {method.getDeclaringClass().getName(), method.getName()}));
        result.setStatus(Result.FAILED);
        // return true;
      }
    } catch (ClassNotFoundException e) {
      Verifier.debug(e);
      addErrorDetails(result, compName);
      result.failed(
          smh.getLocalString(
              getClass().getName() + ".failedException",
              "Error: Home interface [ {0} ] does not exist or is not loadable within bean [ {1} ]",
              new Object[] {getClassName(descriptor), descriptor.getName()}));
      // return false;
      result.setStatus(Result.FAILED);
    }
  }
Example #9
0
  @Override
  public HandlerProcessingResult processAnnotation(AnnotationInfo annInfo)
      throws AnnotationProcessorException {
    AnnotatedElementHandler annCtx = annInfo.getProcessingContext().getHandler();
    AnnotatedElement annElem = annInfo.getAnnotatedElement();
    AnnotatedElement origAnnElem = annElem;

    boolean ejbInWar = ignoreWebserviceAnnotations(annElem, annCtx);
    // Bug  http://monaco.sfbay/detail.jsf?cr=6956406
    // When there is an ejb webservice packaged in a war
    // ignore the annotation processing for WebBundleDescriptor
    // In Ejb webservice in a war there are 2 bundle descriptors
    // so we should just allow the processing for the EjbBundleDescriptor
    // and add webservices to that BundleDescriptor
    if (ejbInWar) {
      return HandlerProcessingResultImpl.getDefaultResult(
          getAnnotationType(), ResultType.PROCESSED);
    }

    // sanity check
    if (!(annElem instanceof Class)) {
      AnnotationProcessorException ape =
          new AnnotationProcessorException(
              wsLocalStrings.getLocalString(
                  "enterprise.deployment.annotation.handlers.wrongannotationlocation",
                  "WS00022: symbol annotation can only be specified on TYPE"),
              annInfo);
      annInfo.getProcessingContext().getErrorHandler().error(ape);
      return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.FAILED);
    }

    // Ignore @WebService annotation on an interface; process only those in an actual service impl
    // class
    if (((Class) annElem).isInterface()) {
      return HandlerProcessingResultImpl.getDefaultResult(
          getAnnotationType(), ResultType.PROCESSED);
    }

    if (isJaxwsRIDeployment(annInfo)) {
      // Looks like JAX-WS RI specific deployment, do not process Web Service annotations otherwise
      // would end up as two web service endpoints
      conLogger.log(
          Level.INFO,
          LogUtils.DEPLOYMENT_DISABLED,
          new Object[] {
            annInfo.getProcessingContext().getArchive().getName(), "WEB-INF/sun-jaxws.xml"
          });
      return HandlerProcessingResultImpl.getDefaultResult(
          getAnnotationType(), ResultType.PROCESSED);
    }

    // let's get the main annotation of interest.
    javax.jws.WebService ann = (javax.jws.WebService) annInfo.getAnnotation();

    BundleDescriptor bundleDesc = null;

    // Ensure that an EJB endpoint is packaged in EJBJAR and a servlet endpoint is packaged in a WAR
    try {
      /*  TODO These conditions will change since ejb in war will be supported
      //uncomment if needed
           if(annCtx instanceof EjbContext &&   (provider !=null) &&
                  (provider.getType("javax.ejb.Stateless") == null)) {
              AnnotationProcessorException ape = new AnnotationProcessorException(
                      localStrings.getLocalString("enterprise.deployment.annotation.handlers.webeppkgwrong",
                              "Class {0} is annotated with @WebService and without @Stateless
                               but is packaged in a JAR." +
                               " If it is supposed to be a servlet endpoint, it should be
                                packaged in a WAR; Deployment will continue assuming  this " +
                                "class to be just a POJO used by other classes in the JAR  being deployed",
                              new Object[] {((Class)annElem).getName()}),annInfo);
              ape.setFatal(false);
              throw ape;
          }

          if(annCtx instanceof EjbBundleContext && (provider !=null) &&
                  (provider.getType("javax.ejb.Stateless") == null)) {
              AnnotationProcessorException ape = new AnnotationProcessorException(
                      localStrings.getLocalString  ("enterprise.deployment.annotation.handlers.webeppkgwrong",
                              "Class {0} is annotated with @WebService and without @Stateless but is packaged in a JAR." +
                                      " If it is supposed to be a servlet endpoint, it should be packaged in a WAR; Deployment will continue assuming this " +
                                      "class to be just a POJO used by other classes in the JARbeing deployed",
                              new Object[] {((Class)annElem).getName()}),annInfo);
              ape.setFatal(false);
              throw ape;
          }
          if(annCtx instanceof WebBundleContext && (provider !=null) &&
                  (provider.getType("javax.ejb.Stateless") != null)) {
              AnnotationProcessorException ape = new AnnotationProcessorException(
                      localStrings.getLocalString
                       ("enterprise.deployment.annotation.handlers.ejbeppkgwrong",
                       "Class {0} is annotated with @WebService and @Stateless but is packaged in a WAR." +" If it is supposed to be an EJB endpoint, it should be  packaged in a JAR; Deployment will continue assuming this "
                      +" class to be just a POJO used by other classes in the WAR being deployed",
                              new Object[] {((Class)annElem).getName()}),annInfo);
              ape.setFatal(false);
              throw ape;
          }*/

      // let's see the type of web service we are dealing with...
      if ((ejbProvider != null)
          && ejbProvider.getType("javax.ejb.Stateless") != null
          && (annCtx instanceof EjbContext)) {
        // this is an ejb !
        EjbContext ctx = (EjbContext) annCtx;
        bundleDesc = ctx.getDescriptor().getEjbBundleDescriptor();
        bundleDesc.setSpecVersion("3.0");
      } else {
        // this has to be a servlet since there is no @Servlet annotation yet
        if (annCtx instanceof WebComponentContext) {
          bundleDesc = ((WebComponentContext) annCtx).getDescriptor().getWebBundleDescriptor();
        } else if (!(annCtx instanceof WebBundleContext)) {
          return getInvalidAnnotatedElementHandlerResult(
              annInfo.getProcessingContext().getHandler(), annInfo);
        }

        bundleDesc = ((WebBundleContext) annCtx).getDescriptor();

        bundleDesc.setSpecVersion("2.5");
      }
    } catch (Exception e) {
      throw new AnnotationProcessorException(
          wsLocalStrings.getLocalString(
              "webservice.annotation.exception",
              "WS00023: Exception in processing @Webservice : {0}",
              e.getMessage()));
    }
    // WebService.name in the impl class identifies port-component-name
    // If this is specified in impl class, then that takes precedence
    String portComponentName = ann.name();

    // As per JSR181, the serviceName is either specified in the deployment descriptor
    // or in @WebSErvice annotation in impl class; if neither service name implclass+Service
    String svcNameFromImplClass = ann.serviceName();
    String implClassName = ((Class) annElem).getSimpleName();
    String implClassFullName = ((Class) annElem).getName();

    // In case user gives targetNameSpace in the Impl class, that has to be used as
    // the namespace for service, port; typically user will do this in cases where
    // port_types reside in a different namespace than that of server/port.
    // Store the targetNameSpace, if any, in the impl class for later use
    String targetNameSpace = ann.targetNamespace();

    // As per JSR181, the portName is either specified in deployment desc or in @WebService
    // in impl class; if neither, it will @WebService.name+Port; if @WebService.name is not there,
    // then port name is implClass+Port
    String portNameFromImplClass = ann.portName();
    if ((portNameFromImplClass == null) || (portNameFromImplClass.length() == 0)) {
      if ((portComponentName != null) && (portComponentName.length() != 0)) {
        portNameFromImplClass = portComponentName + "Port";
      } else {
        portNameFromImplClass = implClassName + "Port";
      }
    }

    // Store binding type specified in Impl class
    String userSpecifiedBinding = null;
    javax.xml.ws.BindingType bindingAnn =
        (javax.xml.ws.BindingType) ((Class) annElem).getAnnotation(javax.xml.ws.BindingType.class);
    if (bindingAnn != null) {
      userSpecifiedBinding = bindingAnn.value();
    }

    // Store wsdlLocation in the impl class (if any)
    String wsdlLocation = null;
    if (ann.wsdlLocation() != null && ann.wsdlLocation().length() != 0) {
      wsdlLocation = ann.wsdlLocation();
    }

    // At this point, we need to check if the @WebService points to an SEI
    // with the endpointInterface attribute, if that is the case, the
    // remaining attributes should be extracted from the SEI instead of SIB.
    if (ann.endpointInterface() != null && ann.endpointInterface().length() > 0) {
      Class endpointIntf;
      try {
        endpointIntf = ((Class) annElem).getClassLoader().loadClass(ann.endpointInterface());
      } catch (java.lang.ClassNotFoundException cfne) {
        throw new AnnotationProcessorException(
            localStrings.getLocalString(
                "enterprise.deployment.annotation.handlers.classnotfound",
                "class {0} referenced from annotation symbol cannot be loaded",
                new Object[] {ann.endpointInterface()}),
            annInfo);
      }
      annElem = endpointIntf;

      ann = annElem.getAnnotation(javax.jws.WebService.class);
      if (ann == null) {
        throw new AnnotationProcessorException(
            wsLocalStrings.getLocalString(
                "no.webservice.annotation",
                "WS00025: SEI {0} referenced from the @WebService annotation on {1}  does not contain a @WebService annotation",
                ((javax.jws.WebService) annInfo.getAnnotation()).endpointInterface(),
                ((Class) annElem).getName()));
      }

      // SEI cannot have @BindingType
      if (annElem.getAnnotation(javax.xml.ws.BindingType.class) != null) {
        throw new AnnotationProcessorException(
            wsLocalStrings.getLocalString(
                "cannot.have.bindingtype",
                "WS00026: SEI {0} cannot have @BindingType",
                ((javax.jws.WebService) annInfo.getAnnotation()).endpointInterface()));
      }
    }

    WebServicesDescriptor wsDesc = bundleDesc.getWebServices();
    // WebService.name not found; as per 109, default port-component-name
    // is the simple class name as long as the simple class name will be a
    // unique port-component-name for this module
    if (portComponentName == null || portComponentName.length() == 0) {
      portComponentName = implClassName;
    }
    // Check if this port-component-name is unique for this module
    WebServiceEndpoint wep = wsDesc.getEndpointByName(portComponentName);
    if (wep != null) {
      // there is another port-component by this name in this module;
      // now we have to look at the SEI/impl of that port-component; if that SEI/impl
      // is the same as the current SEI/impl then it means we have to override values;
      // If the SEI/impl classes do not match, then no overriding should happen; we should
      // use fully qualified class name as port-component-name for the current endpoint
      if ((wep.getServiceEndpointInterface() != null)
          && (wep.getServiceEndpointInterface().length() != 0)
          && (!((Class) annElem).getName().equals(wep.getServiceEndpointInterface()))) {
        portComponentName = implClassFullName;
      }
    }

    // Check if the same endpoint is already defined in webservices.xml
    // This has to be done again after applying the 109 rules as above
    // for port-component-name
    WebServiceEndpoint endpoint = wsDesc.getEndpointByName(portComponentName);
    WebService newWS;
    if (endpoint == null) {
      if (DOLUtils.warType().equals(bundleDesc.getModuleType())) {
        // http://java.net/jira/browse/GLASSFISH-17204
        WebComponentDescriptor[] wcByImplName =
            ((WebBundleDescriptor) bundleDesc).getWebComponentByImplName(implClassFullName);
        for (WebComponentDescriptor wc : wcByImplName) {
          if (!wsDesc.getEndpointsImplementedBy(wc).isEmpty()) {
            // URL mapping for annotated service exists - it can be JAX-RPC service
            // as well as some servlet or maybe only invalid port-component-name,
            // so let user know about possible error
            logger.log(
                Level.SEVERE, LogUtils.WS_URLMAPPING_EXISTS, new Object[] {implClassFullName});
            break;
          }
        }
      }
      // Check if a service with the same name is already present
      // If so, add this endpoint to the existing service
      if (svcNameFromImplClass != null && svcNameFromImplClass.length() != 0) {
        newWS = wsDesc.getWebServiceByName(svcNameFromImplClass);
      } else {
        newWS = wsDesc.getWebServiceByName(implClassName + "Service");
      }
      if (newWS == null) {
        newWS = new WebService();
        // service name from annotation
        if (svcNameFromImplClass != null && svcNameFromImplClass.length() != 0) {
          newWS.setName(svcNameFromImplClass);
        } else {
          newWS.setName(implClassName + "Service");
        }
        wsDesc.addWebService(newWS);
      }
      endpoint = new WebServiceEndpoint();
      if (portComponentName != null && portComponentName.length() != 0) {
        endpoint.setEndpointName(portComponentName);
      } else {
        endpoint.setEndpointName(((Class) annElem).getName());
      }
      newWS.addEndpoint(endpoint);
      wsDesc.setSpecVersion(WebServicesDescriptorNode.SPEC_VERSION);
    } else {
      newWS = endpoint.getWebService();
    }

    // If wsdl-service is specified in the descriptor, then the targetnamespace
    // in wsdl-service should match the @WebService.targetNameSpace, if any.
    // make that assertion here - and the targetnamespace in wsdl-service, if
    // present overrides everything else
    if (endpoint.getWsdlService() != null) {
      if ((targetNameSpace != null)
          && (targetNameSpace.length() != 0)
          && (!endpoint.getWsdlService().getNamespaceURI().equals(targetNameSpace))) {
        AnnotationProcessorException ape =
            new AnnotationProcessorException(
                wsLocalStrings.getLocalString(
                    "mismatch.targetnamespace",
                    "WS00027: Target Namespace in wsdl-service element does not match @WebService.targetNamespace"),
                annInfo);
        annInfo.getProcessingContext().getErrorHandler().error(ape);
        return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.FAILED);
      }
      targetNameSpace = endpoint.getWsdlService().getNamespaceURI();
    }

    // Service and port should reside in the same namespace - assert that
    if ((endpoint.getWsdlService() != null) && (endpoint.getWsdlPort() != null)) {
      if (!endpoint
          .getWsdlService()
          .getNamespaceURI()
          .equals(endpoint.getWsdlPort().getNamespaceURI())) {
        AnnotationProcessorException ape =
            new AnnotationProcessorException(
                wsLocalStrings.getLocalString(
                    "mismatch.port.targetnamespace",
                    "WS00028: Target Namespace for wsdl-service and wsdl-port should be the same"),
                annInfo);
        annInfo.getProcessingContext().getErrorHandler().error(ape);
        return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.FAILED);
      }
    }

    // Use annotated values only if the deployment descriptor equivalen has not been specified

    // If wsdlLocation was not given in Impl class, see if it is present in SEI
    // Set this in DOL if there is no Depl Desc entry
    // Precedence given for wsdlLocation in impl class
    if (newWS.getWsdlFileUri() == null) {
      if (wsdlLocation != null) {
        newWS.setWsdlFileUri(wsdlLocation);
      } else {
        if (ann.wsdlLocation() != null && ann.wsdlLocation().length() != 0) {
          newWS.setWsdlFileUri(ann.wsdlLocation());
        }
      }
    }

    // Set binding id id @BindingType is specified by the user in the impl class
    if ((!endpoint.hasUserSpecifiedProtocolBinding())
        && (userSpecifiedBinding != null)
        && (userSpecifiedBinding.length() != 0)) {
      endpoint.setProtocolBinding(userSpecifiedBinding);
    }

    if (endpoint.getServiceEndpointInterface() == null) {
      // take SEI from annotation
      if (ann.endpointInterface() != null && ann.endpointInterface().length() != 0) {
        endpoint.setServiceEndpointInterface(ann.endpointInterface());
      } else {
        endpoint.setServiceEndpointInterface(((Class) annElem).getName());
      }
    }

    // at this point the SIB has to be used no matter what @WebService was used.
    annElem = annInfo.getAnnotatedElement();

    if (DOLUtils.warType().equals(bundleDesc.getModuleType())) {
      if (endpoint.getServletImplClass() == null) {
        // Set servlet impl class here
        endpoint.setServletImplClass(((Class) annElem).getName());
      }

      // Servlet link name
      WebBundleDescriptor webBundle = (WebBundleDescriptor) bundleDesc;
      if (endpoint.getWebComponentLink() == null) {
        // <servlet-link> = fully qualified name of the implementation class
        endpoint.setWebComponentLink(implClassFullName);
      }
      if (endpoint.getWebComponentImpl() == null) {
        WebComponentDescriptor webComponent =
            (WebComponentDescriptor)
                webBundle.getWebComponentByCanonicalName(endpoint.getWebComponentLink());

        if (webComponent == null) {
          // GLASSFISH-3297
          WebComponentDescriptor[] wcs = webBundle.getWebComponentByImplName(implClassFullName);
          if (wcs.length > 0) {
            webComponent = wcs[0];
          }
        }

        // if servlet is not known, we should add it now
        if (webComponent == null) {
          webComponent = new WebComponentDescriptorImpl();
          webComponent.setServlet(true);
          webComponent.setWebComponentImplementation(((Class) annElem).getCanonicalName());
          webComponent.setName(endpoint.getEndpointName());
          webComponent.addUrlPattern("/" + newWS.getName());
          webBundle.addWebComponentDescriptor(webComponent);
        }
        endpoint.setWebComponentImpl(webComponent);
      }
    } else {

      // TODO BM handle stateless
      Stateless stateless = null;
      try {
        stateless = annElem.getAnnotation(javax.ejb.Stateless.class);
      } catch (Exception e) {
        if (logger.isLoggable(Level.FINE)) {
          // This can happen in the web.zip installation where there is no ejb
          // Just logging the error
          conLogger.log(Level.FINE, LogUtils.EXCEPTION_THROWN, e);
        }
      }
      Singleton singleton = null;
      try {
        singleton = annElem.getAnnotation(javax.ejb.Singleton.class);
      } catch (Exception e) {
        if (logger.isLoggable(Level.FINE)) {
          // This can happen in the web.zip installation where there is no ejb
          // Just logging the error
          conLogger.log(Level.FINE, LogUtils.EXCEPTION_THROWN, e);
        }
      }
      String name;

      if ((stateless != null) && ((stateless).name() == null || stateless.name().length() > 0)) {
        name = stateless.name();
      } else if ((singleton != null)
          && ((singleton).name() == null || singleton.name().length() > 0)) {
        name = singleton.name();

      } else {
        name = ((Class) annElem).getSimpleName();
      }
      EjbDescriptor ejb = ((EjbBundleDescriptor) bundleDesc).getEjbByName(name);
      endpoint.setEjbComponentImpl(ejb);
      ejb.setWebServiceEndpointInterfaceName(endpoint.getServiceEndpointInterface());
      if (endpoint.getEjbLink() == null) endpoint.setEjbLink(ejb.getName());
    }

    if (endpoint.getWsdlPort() == null) {
      // Use targetNameSpace given in wsdl-service/Impl class for port and service
      // If none, derive the namespace from package name and this will be used for
      // service and port - targetNamespace, if any, in SEI will be used for pprtType
      // during wsgen phase
      if (targetNameSpace == null || targetNameSpace.length() == 0) {
        // No targerNameSpace anywhere; calculate targetNameSpace and set wsdl port
        // per jax-ws 2.0 spec, the target name is the package name in
        // the reverse order prepended with http://
        if (((Class) annElem).getPackage() != null) {

          StringTokenizer tokens =
              new StringTokenizer(((Class) annElem).getPackage().getName(), ".", false);

          if (tokens.hasMoreElements()) {
            while (tokens.hasMoreElements()) {
              if (targetNameSpace == null || targetNameSpace.length() == 0) {
                targetNameSpace = tokens.nextElement().toString();
              } else {
                targetNameSpace = tokens.nextElement().toString() + "." + targetNameSpace;
              }
            }
          } else {
            targetNameSpace = ((Class) annElem).getPackage().getName();
          }
        } else {
          throw new AnnotationProcessorException(
              wsLocalStrings.getLocalString(
                  "missing.targetnamespace",
                  "WS00029: The javax.jws.WebService annotation targetNamespace must be used for classes or interfaces that are in no package"));
        }
        targetNameSpace = "http://" + (targetNameSpace == null ? "" : targetNameSpace + "/");
      }
      // WebService.portName = wsdl-port
      endpoint.setWsdlPort(new QName(targetNameSpace, portNameFromImplClass, "ns1"));
    }

    if (endpoint.getWsdlService() == null) {
      // Set wsdl-service properly; namespace is the same as that of wsdl port;
      // service name derived from deployment desc / annotation / default
      String serviceNameSpace = endpoint.getWsdlPort().getNamespaceURI();
      String serviceName = null;
      if ((svcNameFromImplClass != null) && (svcNameFromImplClass.length() != 0)) {
        // Use the serviceName annotation if available
        serviceName = svcNameFromImplClass;
      } else {
        serviceName = newWS.getName();
      }
      endpoint.setWsdlService(new QName(serviceNameSpace, serviceName, "ns1"));
    }

    // Now force a HandlerChain annotation processing
    // This is to take care of the case where the endpoint Impl class does not
    // have @HandlerChain but the SEI has one specified through JAXWS customization
    if ((((Class) origAnnElem).getAnnotation(javax.jws.HandlerChain.class)) == null) {
      return (new HandlerChainHandler())
          .processHandlerChainAnnotation(annInfo, annCtx, origAnnElem, (Class) origAnnElem, true);
    }
    return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.PROCESSED);
  }