Package org.jboss.jca.common.annotations

Source Code of org.jboss.jca.common.annotations.Annotations

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.jca.common.annotations;

import org.jboss.jca.common.validator.ValidateException;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;

import javax.resource.spi.Activation;
import javax.resource.spi.AdministeredObject;
import javax.resource.spi.AuthenticationMechanism;
import javax.resource.spi.AuthenticationMechanism.CredentialInterface;
import javax.resource.spi.ConfigProperty;
import javax.resource.spi.ConnectionDefinition;
import javax.resource.spi.ConnectionDefinitions;
import javax.resource.spi.Connector;
import javax.resource.spi.SecurityPermission;
import javax.resource.spi.TransactionSupport;
import javax.resource.spi.TransactionSupport.TransactionSupportLevel;
import javax.resource.spi.work.WorkContext;

import org.jboss.logging.Logger;

import org.jboss.metadata.javaee.spec.DescriptionGroupMetaData;
import org.jboss.metadata.javaee.spec.DescriptionImpl;
import org.jboss.metadata.javaee.spec.DescriptionsImpl;
import org.jboss.metadata.javaee.spec.DisplayNameImpl;
import org.jboss.metadata.javaee.spec.DisplayNamesImpl;
import org.jboss.metadata.javaee.spec.IconImpl;
import org.jboss.metadata.javaee.spec.IconsImpl;

import org.jboss.metadata.rar.spec.ActivationspecMetaData;
import org.jboss.metadata.rar.spec.AdminObjectMetaData;
import org.jboss.metadata.rar.spec.AuthenticationMechanismMetaData;
import org.jboss.metadata.rar.spec.ConfigPropertyMetaData;
import org.jboss.metadata.rar.spec.ConnectionDefinitionMetaData;
import org.jboss.metadata.rar.spec.ConnectorMetaData;
import org.jboss.metadata.rar.spec.InboundRaMetaData;
import org.jboss.metadata.rar.spec.JCA16Base;
import org.jboss.metadata.rar.spec.JCA16MetaData;
import org.jboss.metadata.rar.spec.LicenseMetaData;
import org.jboss.metadata.rar.spec.MessageAdapterMetaData;
import org.jboss.metadata.rar.spec.MessageListenerMetaData;
import org.jboss.metadata.rar.spec.OutboundRaMetaData;
import org.jboss.metadata.rar.spec.ResourceAdapterMetaData;
import org.jboss.metadata.rar.spec.SecurityPermissionMetaData;
import org.jboss.metadata.rar.spec.TransactionSupportMetaData;

import org.jboss.papaki.Annotation;
import org.jboss.papaki.AnnotationRepository;
import org.jboss.papaki.AnnotationScanner;
import org.jboss.papaki.AnnotationScannerFactory;
import org.jboss.papaki.AnnotationType;

/**
* The annotation processor for JCA 1.6
* @author <a href="mailto:jesper.pedersen@jboss.org">Jesper Pedersen</a>
*/
public class Annotations
{
   private static Logger log = Logger.getLogger(Annotations.class);
   private static boolean trace = log.isTraceEnabled();

   /**
    * Constructor
    */
   public Annotations()
   {
   }

   /**
    * Scan for annotations in the URLs specified
    * @param cmd The resource adapter metadata
    * @param urls The URLs to be scanned
    * @param cl The referenced classloader
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   public ConnectorMetaData scan(ConnectorMetaData cmd, URL[] urls, ClassLoader cl) throws Exception
   {
      // Process annotations
      if (cmd == null || cmd.is16())
      {
         AnnotationScanner annotationScanner =
            AnnotationScannerFactory.getStrategy(AnnotationScannerFactory.JAVASSIST_INPUT_STREAM);
         annotationScanner.configure().constructorLevel(false).parameterLevel(false);
         AnnotationRepository annotationRepository = annotationScanner.scan(urls, cl);

         boolean isMetadataComplete = false;
         if (cmd != null && cmd instanceof JCA16Base)
         {
            JCA16Base jmd = (JCA16Base)cmd;
            isMetadataComplete = jmd.isMetadataComplete();
         }
        
         if (cmd == null || !isMetadataComplete)
         {
            cmd = process(cmd, annotationRepository);
         }
      }
      return cmd;
   }
   /**
    * Process annotations
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   public ConnectorMetaData process(ConnectorMetaData md, AnnotationRepository annotationRepository)
      throws Exception
   {
      if (annotationRepository == null)
         throw new ValidateException("AnnotationRepository reference is null");
      /* Process
         -------
         javax.resource.spi.Activation
         javax.resource.spi.AdministeredObject
         javax.resource.spi.AuthenticationMechanism
         javax.resource.spi.ConfigProperty
         javax.resource.spi.ConnectionDefinition
         javax.resource.spi.ConnectionDefinitions
         javax.resource.spi.Connector
         javax.resource.spi.SecurityPermission
      */
     
      if (md == null)
      {
         JCA16MetaData jmd = new JCA16MetaData();
         jmd.setMetadataComplete(false);
         md = jmd;
      }

      // @Connector
      md = processConnector(md, annotationRepository);

      // @ConnectionDefinitions
      md = processConnectionDefinitions(md, annotationRepository);

      // @ConnectionDefinition (outside of @ConnectionDefinitions)
      md = processConnectionDefinition(md, annotationRepository);

      // @Activation
      md = processActivation(md, annotationRepository);

      // @AuthenticationMechanism
      //md = processAuthenticationMechanism(md, annotationRepository);

      // @AdministeredObject
      md = processAdministeredObject(md, annotationRepository);

      // @ConfigProperty handle at last
      md = processConfigProperty(md, annotationRepository);

      //log.debug("ConnectorMetadata " + md);

      return md;
   }

   /**
    * Process: @Connector
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData processConnector(ConnectorMetaData md, AnnotationRepository annotationRepository)
      throws Exception
   {
      Collection<Annotation> values = annotationRepository.getAnnotation(Connector.class);
      if (values != null)
      {
         if (values.size() == 1)
         {
            Annotation annotation = values.iterator().next();
            String raClass = annotation.getClassName();
            Connector c = (Connector)annotation.getAnnotation();

            if (trace)
               log.trace("Processing: " + c + " for " + raClass);

            md = attachConnector(md, raClass, c);
         }
         else if (values.size() == 0)
         {
            // JBJCA-240
            if (md.getRa().getRaClass() == null || md.getRa().getRaClass().equals(""))
            {
               log.fatal("No @Connector was found and no definition in the ra.xml metadata either");
               throw new ValidateException("No @Connector defined");
            }
         }
         else
         {
            // JBJCA-240
            if (md.getRa().getRaClass() == null || md.getRa().getRaClass().equals(""))
            {
               log.fatal("More than one @Connector was found but the correct one " +
                         "wasn't defined in the ra.xml metadata");
               throw new ValidateException("More than one @Connector defined");
            }
         }
      }

      return md;
   }

   /**
    * Attach @Connector
    * @param md The metadata
    * @param raClass The class name for the resource adapter
    * @param c The connector
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachConnector(ConnectorMetaData md, String raClass, Connector c)
      throws Exception
   {
      // Class definition
      if (md.getRa() == null)
         md.setRa(new ResourceAdapterMetaData());

      md.getRa().setRaClass(raClass);

      // AuthenticationMechanism
      AuthenticationMechanism[] authMechanisms = c.authMechanisms();
      if (authMechanisms != null)
      {
         for (AuthenticationMechanism authMechanism : authMechanisms)
         {
            attachAuthenticationMechanism(md, authMechanism);
         }
      }

      DescriptionGroupMetaData descGroup = new DescriptionGroupMetaData();
      md.setDescriptionGroup(descGroup);
     
      // Description
      String[] description = c.description();
      if (description != null)
      {
         if (descGroup.getDescriptions() == null)
         {
            DescriptionsImpl descsImpl = new DescriptionsImpl();
            descGroup.setDescriptions(descsImpl);
         }
         for (String desc : description)
         {
            DescriptionImpl descImpl = new DescriptionImpl();
            descImpl.setDescription(desc);
            ((DescriptionsImpl)descGroup.getDescriptions()).add(descImpl);
         }
      }

      // Display name
      String[] displayName = c.displayName();
      if (displayName != null)
      {
         if (descGroup.getDisplayNames() == null)
         {
            DisplayNamesImpl dnsImpl = new DisplayNamesImpl();
            descGroup.setDisplayNames(dnsImpl);
         }
         for (String dn : displayName)
         {
            DisplayNameImpl dnImpl = new DisplayNameImpl();
            dnImpl.setDisplayName(dn);
            ((DisplayNamesImpl)descGroup.getDisplayNames()).add(dnImpl);
         }
      }

      // EIS type
      String eisType = c.eisType();
      if (eisType != null)
      {
         if (md.getEISType() == null)
            md.setEISType(eisType);
      }

      // Large icon
      String[] largeIcon = c.largeIcon();
      if (largeIcon != null)
      {
         if (descGroup.getIcons() == null)
         {
            IconsImpl icsImpl = new IconsImpl();
            descGroup.setIcons(icsImpl);
         }
         for (String large : largeIcon)
         {
            IconImpl icImpl = new IconImpl();
            icImpl.setLargeIcon(large);
            ((IconsImpl)descGroup.getIcons()).add(icImpl);
         }
      }

      // License description
      String[] licenseDescription = c.licenseDescription();
      if (licenseDescription != null)
      {
         if (md.getLicense() == null)
            md.setLicense(new LicenseMetaData());

         if (md.getLicense().getDescriptions() == null)
         {
            DescriptionsImpl descsImpl = new DescriptionsImpl();
            md.getLicense().setDescriptions(descsImpl);
         }
         for (String desc : licenseDescription)
         {
            DescriptionImpl descImpl = new DescriptionImpl();
            descImpl.setDescription(desc);
            ((DescriptionsImpl)md.getLicense().getDescriptions()).add(descImpl);
         }
      }

      // License required
      boolean licenseRequired = c.licenseRequired();
      if (md.getLicense() == null)
         md.setLicense(new LicenseMetaData());
      md.getLicense().setRequired(licenseRequired);

      // Reauthentication support
      boolean reauthenticationSupport = c.reauthenticationSupport();
      if (md.getRa() != null && md.getRa().getOutboundRa() != null)
      {
         md.getRa().getOutboundRa().setReAuthSupport(reauthenticationSupport);
      }

      // RequiredWorkContext
      Class<? extends WorkContext>[] requiredWorkContexts = c.requiredWorkContexts();
      if (requiredWorkContexts != null)
      {
         for (Class<? extends WorkContext> requiredWorkContext : requiredWorkContexts)
         {
            if (md instanceof JCA16Base)
            {
               JCA16Base jmd = (JCA16Base)md;
               if (jmd.getRequiredWorkContexts() == null)
                  jmd.setRequiredWorkContexts(new ArrayList<String>());

               if (!jmd.getRequiredWorkContexts().contains(requiredWorkContext.getName()))
               {
                  if (trace)
                     log.trace("RequiredWorkContext=" + requiredWorkContext.getName());

                  jmd.getRequiredWorkContexts().add(requiredWorkContext.getName());
               }
            }
         }
      }

      // Security permission
      SecurityPermission[] securityPermissions = c.securityPermissions();
      if (securityPermissions != null)
      {
         if (md.getRa() == null)
            md.setRa(new ResourceAdapterMetaData());

         if (md.getRa().getSecurityPermissions() == null)
            md.getRa().setSecurityPermissions(new ArrayList<SecurityPermissionMetaData>());

         for (SecurityPermission securityPermission : securityPermissions)
         {
            SecurityPermissionMetaData spmd = new SecurityPermissionMetaData();
            spmd.setSecurityPermissionSpec(securityPermission.permissionSpec());
            md.getRa().getSecurityPermissions().add(spmd);
         }
      }

      // Small icon
      String[] smallIcon = c.smallIcon();
      if (smallIcon != null)
      {
         IconsImpl icsImpl;
         if (descGroup.getIcons() == null)
         {
            icsImpl = new IconsImpl();
            descGroup.setIcons(icsImpl);
         }
         else
         {
            icsImpl = (IconsImpl)descGroup.getIcons();
         }
         IconImpl[] icArray = icsImpl.toArray(new IconImpl[icsImpl.size()]);
         for (int i = 0; i < smallIcon.length; i++)
         {
            if (i < icArray.length)
               icArray[i].setSmallIcon(smallIcon[i]);
            else
            {
               IconImpl icImpl = new IconImpl();
               icImpl.setLargeIcon(smallIcon[i]);
               icsImpl.add(icImpl);
            }
         }
      }

      // Transaction support
      TransactionSupport.TransactionSupportLevel transactionSupport = c.transactionSupport();
      if (md.getRa() != null && md.getRa().getOutboundRa() != null)
      {
         if (transactionSupport.equals(TransactionSupportLevel.NoTransaction))
         {
            md.getRa().getOutboundRa().setTransSupport(TransactionSupportMetaData.NoTransaction);
         }
         else if (transactionSupport.equals(TransactionSupportLevel.XATransaction))
         {
            md.getRa().getOutboundRa().setTransSupport(TransactionSupportMetaData.XATransaction);
         }
         else if (transactionSupport.equals(TransactionSupportLevel.LocalTransaction))
         {
            md.getRa().getOutboundRa().setTransSupport(TransactionSupportMetaData.LocalTransaction);
         }
      }

      // Vendor name
      String vendorName = c.vendorName();
      if (vendorName != null)
      {
         if (md.getVendorName() == null)
            md.setVendorName(vendorName);
      }

      // Version
      String version = c.version();
      if (version != null)
      {
         if (md.getRAVersion() == null)
            md.setRAVersion(version);
      }

      return md;
   }

   /**
    * Process: @ConnectionDefinitions
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData processConnectionDefinitions(ConnectorMetaData md,
                                                          AnnotationRepository annotationRepository)
      throws Exception
   {
      Collection<Annotation> values = annotationRepository.getAnnotation(ConnectionDefinitions.class);
      if (values != null)
      {
         if (values.size() == 1)
         {
            Annotation annotation = values.iterator().next();
            ConnectionDefinitions c = (ConnectionDefinitions)annotation.getAnnotation();

            if (trace)
               log.trace("Processing: " + c);

            md = attachConnectionDefinitions(md , c, annotation.getClassName());
         }
         else
            throw new ValidateException("More than one @ConnectionDefinitions defined");
      }

      return md;
   }

   /**
    * Attach @ConnectionDefinitions
    * @param md The metadata
    * @param cds The connection definitions
    * @param mcf The managed connection factory
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachConnectionDefinitions(ConnectorMetaData md,
                                                         ConnectionDefinitions cds,
                                                         String mcf)
      throws Exception
   {
      createConDefs(md);

      if (cds.value() != null)
      {
         for (ConnectionDefinition cd : cds.value())
         {
            md = attachConnectionDefinition(md, mcf, cd);
         }
      }

      return md;
   }

   /**
    * Process: @ConnectionDefinition
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData processConnectionDefinition(ConnectorMetaData md,
                                                         AnnotationRepository annotationRepository)
      throws Exception
   {
      Collection<Annotation> values = annotationRepository.getAnnotation(ConnectionDefinition.class);
      if (values != null)
      {
         for (Annotation annotation : values)
         {
            md = attachConnectionDefinition(md, annotation);
         }
      }

      return md;
   }

   /**
    * Attach @ConnectionDefinition
    * @param md The metadata
    * @param cd The connection definition
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachConnectionDefinition(ConnectorMetaData md, Annotation annotation)
      throws Exception
   {
      ConnectionDefinition cd = (ConnectionDefinition)annotation.getAnnotation();

      if (trace)
         log.trace("Processing: " + annotation);

      createConDefs(md);

      for (ConnectionDefinitionMetaData cdMeta : md.getRa().getOutboundRa().getConDefs())
      {
         if (cdMeta.getManagedConnectionFactoryClass().equals(annotation.getClassName()))
         {
            //ra.xml define
            return md;
         }
      }

      return attachConnectionDefinition(md, annotation.getClassName(), cd);
   }

   /**
    * Attach @ConnectionDefinition
    * @param md The metadata
    * @param mcf The managed connection factory
    * @param cd The connection definition
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachConnectionDefinition(ConnectorMetaData md,
                                                        String mcf,
                                                        ConnectionDefinition cd)
      throws Exception
   {
      if (trace)
         log.trace("Processing: " + cd);

      createConDefs(md);

      ConnectionDefinitionMetaData cdMeta = new ConnectionDefinitionMetaData();
      cdMeta.setManagedConnectionFactoryClass(mcf);
      cdMeta.setConnectionFactoryInterfaceClass(cd.connectionFactory().getName());
      cdMeta.setConnectionFactoryImplementationClass(cd.connectionFactoryImpl().getName());
      cdMeta.setConnectionInterfaceClass(cd.connection().getName());
      cdMeta.setConnectionImplementationClass(cd.connectionImpl().getName());
      md.getRa().getOutboundRa().getConDefs().add(cdMeta);
      return md;
   }

   /**
    * Process: @ConfigProperty
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData processConfigProperty(ConnectorMetaData md,
                                                          AnnotationRepository annotationRepository)
      throws Exception
   {
      Collection<Annotation> values = annotationRepository.getAnnotation(ConfigProperty.class);
      if (values != null)
      {
         for (Annotation annotation : values)
         {
            md = attachConfigProperty(md, annotation);
         }
      }

      return md;
   }

   /**
    * Attach @ConfigProperty
    * @param md The metadata
    * @param configProperty The config property
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachConfigProperty(ConnectorMetaData md, Annotation annotation)
      throws Exception
   {
      ConfigProperty configProperty = (ConfigProperty)annotation.getAnnotation();

      if (trace)
         log.trace("Processing: " + configProperty);

      // Ignore config-property which has ignore=true
      if (configProperty.ignore())
         return md;

      ConfigPropertyMetaData cfgMeta = new ConfigPropertyMetaData();
      cfgMeta.setName(getConfigPropertyName(annotation));

      if (configProperty.defaultValue() != null && !configProperty.defaultValue().equals(""))
         cfgMeta.setValue(configProperty.defaultValue());

      if (!Object.class.equals(configProperty.type()))
      {
         cfgMeta.setType(configProperty.type().getName());
      }
      else
      {
         cfgMeta.setType(getConfigPropertyType(annotation));
      }
      cfgMeta.setIgnore(configProperty.ignore());

      String[] description = configProperty.description();
      if (description != null)
      {
         if (cfgMeta.getDescriptions() == null)
         {
            DescriptionsImpl descsImpl = new DescriptionsImpl();
            cfgMeta.setDescriptions(descsImpl);
         }
         for (String desc : description)
         {
            DescriptionImpl descImpl = new DescriptionImpl();
            descImpl.setDescription(desc);
            ((DescriptionsImpl)cfgMeta.getDescriptions()).add(descImpl);
         }
      }
     
      String attachedClassName = annotation.getClassName();
      ClassLoader cl = SecurityActions.getThreadContextClassLoader();
      Class attachedClass = Class.forName(attachedClassName, true, cl);

      if (hasInterface(attachedClass, "javax.resource.spi.ResourceAdapter"))
      {
         if (md.getRa() == null)
         {
            md.setRa(new ResourceAdapterMetaData());
         }
         if (md.getRa().getConfigProperty() == null)
         {
            md.getRa().setConfigProperty(new ArrayList<ConfigPropertyMetaData>());
         }
         for (ConfigPropertyMetaData cpMeta : md.getRa().getConfigProperty())
         {
            if (cpMeta.getName().equals(cfgMeta.getName()))
            {
               return md;
            }
         }
         md.getRa().getConfigProperty().add(cfgMeta);
      }
      else if (hasInterface(attachedClass, "javax.resource.spi.ManagedConnectionFactory"))
      {
         createConDefs(md);
         for (ConnectionDefinitionMetaData cdMeta : md.getRa().getOutboundRa().getConDefs())
         {
            if (attachedClassName.equals(cdMeta.getManagedConnectionFactoryClass()))
            {
               if (cdMeta.getConfigProps() == null)
               {
                  cdMeta.setConfigProps(new ArrayList<ConfigPropertyMetaData>());
               }
               for (ConfigPropertyMetaData cpMeta : cdMeta.getConfigProps())
               {
                  if (cpMeta.getName().equals(cfgMeta.getName()))
                  {
                     return md;
                  }
               }
               cdMeta.getConfigProps().add(cfgMeta);
            }
         }
      }
      else if (hasInterface(attachedClass, "javax.resource.spi.ActivationSpec"))
      {
         createMessageListeners(md);
         for (MessageListenerMetaData mlMeta : md.getRa().getInboundRa().getMessageAdapter().getMessageListeners())
         {
            if (attachedClassName.equals(mlMeta.getActivationSpecType().getAsClass()))
            {
               if (mlMeta.getActivationSpecType().getConfigProps() == null)
               {
                  mlMeta.getActivationSpecType().setConfigProps(new ArrayList<ConfigPropertyMetaData>());
               }
               for (ConfigPropertyMetaData cpMeta : mlMeta.getActivationSpecType().getConfigProps())
               {
                  if (cpMeta.getName().equals(cfgMeta.getName()))
                  {
                     return md;
                  }
               }
               mlMeta.getActivationSpecType().getConfigProps().add(cfgMeta);
            }
         }
      }

      return md;
   }

   /**
    * hasInterface
    *
    * @param c
    * @param targetClassName
    * @return
    */
   private boolean hasInterface(Class c, String targetClassName)
   {
      for (Class face : c.getInterfaces())
      {
         if (face.getName().equals(targetClassName))
         {
            return true;
         }
         else
         {
            for (Class face2 : face.getInterfaces())
            {
               if (face2.getName().equals(targetClassName))
               {
                  return true;
               }
               else if (hasInterface(face2, targetClassName))
               {
                  return true;
               }
            }
         }
      }
      if (null != c.getSuperclass())
      {
         return hasInterface(c.getSuperclass(), targetClassName);
      }
      return false;
   }

   /**
    * Attach @AuthenticationMechanism
    * @param md The metadata
    * @param authenticationmechanism The authentication mechanism
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachAuthenticationMechanism(ConnectorMetaData md,
                                                                  AuthenticationMechanism authenticationmechanism)
      throws Exception
   {
      if (md.getRa() == null)
      {
         md.setRa(new ResourceAdapterMetaData());
      }
      if (md.getRa().getOutboundRa() == null)
      {
         md.getRa().setOutboundRa(new OutboundRaMetaData());
      }
      if (md.getRa().getOutboundRa().getAuthMechanisms() == null)
      {
         md.getRa().getOutboundRa().setAuthMechanisms(new ArrayList<AuthenticationMechanismMetaData>());
      }
      AuthenticationMechanismMetaData ammd = new AuthenticationMechanismMetaData();
      ammd.setAuthenticationMechanismType(authenticationmechanism.authMechanism());
     
      String credentialInterfaceClass = null;
      if (authenticationmechanism.credentialInterface().equals(CredentialInterface.GenericCredential))
      {
         credentialInterfaceClass = "javax.resource.spi.security.GenericCredential";
      }
      else if (authenticationmechanism.credentialInterface().equals(CredentialInterface.GSSCredential))
      {
         credentialInterfaceClass = "org.ietf.jgss.GSSCredential";
      }
      else if (authenticationmechanism.credentialInterface().equals(CredentialInterface.PasswordCredential))
      {
         credentialInterfaceClass = "javax.resource.spi.security.PasswordCredential";
      }
      ammd.setCredentialInterfaceClass(credentialInterfaceClass);
     
      String[] description = authenticationmechanism.description();
      if (description != null)
      {
         if (ammd.getDescriptions() == null)
         {
            DescriptionsImpl descsImpl = new DescriptionsImpl();
            ammd.setDescriptions(descsImpl);
         }
         for (String desc : description)
         {
            DescriptionImpl descImpl = new DescriptionImpl();
            descImpl.setDescription(desc);
            ((DescriptionsImpl)ammd.getDescriptions()).add(descImpl);
         }
      }
     
      md.getRa().getOutboundRa().getAuthMechanisms().add(ammd);

      return md;
   }

   /**
    * Process: @AdministeredObject
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData processAdministeredObject(ConnectorMetaData md,
                                                              AnnotationRepository annotationRepository)
      throws Exception
   {
      Collection<Annotation> values = annotationRepository.getAnnotation(AdministeredObject.class);
      if (values != null)
      {
         for (Annotation annotation : values)
         {
            AdministeredObject a = (AdministeredObject)annotation.getAnnotation();

            if (trace)
               log.trace("Processing: " + a);

            md = attachAdministeredObject(md, a);
         }
      }

      return md;
   }

   /**
    * Attach @AdministeredObject
    * @param md The metadata
    * @param a The administered object
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachAdministeredObject(ConnectorMetaData md, AdministeredObject a)
      throws Exception
   {
      createAdminObject(md);
      String aoName = null;
      if (a.adminObjectInterfaces().length > 0)
      {
         aoName = ((Class)Array.get(a.adminObjectInterfaces(), 0)).getName();
      }
      AdminObjectMetaData aomd = new AdminObjectMetaData();
      aomd.setAdminObjectInterfaceClass(aoName);
      md.getRa().getAdminObjects().add(aomd);
      return md;
   }

   /**
    * Process: @Activation
    * @param md The metadata
    * @param annotationRepository The annotation repository
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData processActivation(ConnectorMetaData md,
                                                      AnnotationRepository annotationRepository)
      throws Exception
   {
      Collection<Annotation> values = annotationRepository.getAnnotation(Activation.class);
      if (values != null)
      {
         for (Annotation annotation : values)
         {
            md = attachActivation(md, annotation);
         }
      }

      return md;
   }

   /**
    * Attach @Activation
    * @param md The metadata
    * @param activation The activation
    * @return The updated metadata
    * @exception Exception Thrown if an error occurs
    */
   private ConnectorMetaData attachActivation(ConnectorMetaData md, Annotation annotation)
      throws Exception
   {
      Activation activation = (Activation)annotation.getAnnotation();

      if (trace)
         log.trace("Processing: " + activation);
     
      createMessageListeners(md);
      for (Class asClass : activation.messageListeners())
      {
         ActivationspecMetaData asMeta = new ActivationspecMetaData();
         asMeta.setAsClass(annotation.getClassName());
         MessageListenerMetaData mlMeta = new MessageListenerMetaData();
         mlMeta.setActivationSpecType(asMeta);
         mlMeta.setType(asClass.getName());
         md.getRa().getInboundRa().getMessageAdapter().getMessageListeners().add(mlMeta);
      }
      return md;
   }
  

   /**
    * createMessageListeners
    * @param md
    * @throws Exception
    */
   private void createMessageListeners(ConnectorMetaData md) throws Exception
   {
      if (md.getRa() == null)
      {
         md.setRa(new ResourceAdapterMetaData());
      }
      if (md.getRa().getInboundRa() == null)
      {
         md.getRa().setInboundRa(new InboundRaMetaData());
      }
      if (md.getRa().getInboundRa().getMessageAdapter() == null)
      {
         md.getRa().getInboundRa().setMessageAdapter(new MessageAdapterMetaData());
      }
      if (md.getRa().getInboundRa().getMessageAdapter().getMessageListeners() == null)
      {
         md.getRa().getInboundRa().getMessageAdapter().setMessageListeners(new ArrayList<MessageListenerMetaData>());
      }
   }

   /**
    * createAdminObject
    * @param md
    * @throws Exception
    */
   private void createAdminObject(ConnectorMetaData md) throws Exception
   {
      if (md.getRa() == null)
      {
         md.setRa(new ResourceAdapterMetaData());
      }
      if (md.getRa().getAdminObjects() == null)
      {
         md.getRa().setAdminObjects(new ArrayList<AdminObjectMetaData>());
      }
   }

   /**
    * createConDefs
    * @param md
    * @throws Exception
    */
   private void createConDefs(ConnectorMetaData md) throws Exception
   {
      if (md.getRa() == null)
      {
         md.setRa(new ResourceAdapterMetaData());
      }
      if (md.getRa().getOutboundRa() == null)
      {
         md.getRa().setOutboundRa(new OutboundRaMetaData());
      }
      if (md.getRa().getOutboundRa().getConDefs() == null)
      {
         md.getRa().getOutboundRa().setConDefs(new ArrayList<ConnectionDefinitionMetaData>());
      }
   }

   /**
    * Get the config-property-name for an annotation
    * @param annotation The annotation
    * @return The name
    * @exception ClassNotFoundException Thrown if a class cannot be found
    * @exception NoSuchFieldException Thrown if a field cannot be found
    * @exception NoSuchMethodException Thrown if a method cannot be found
    */
   private String getConfigPropertyName(Annotation annotation)
      throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException
   {
      if (AnnotationType.FIELD.equals(annotation.getType()))
      {
         return annotation.getMemberName();
      }
      else if (AnnotationType.METHOD.equals(annotation.getType()))
      {
         String name = annotation.getMemberName();

         if (name.startsWith("set"))
         {
            name = name.substring(3);
         }
         else if (name.startsWith("get"))
         {
            name = name.substring(3);
         }
         else if (name.startsWith("is"))
         {
            name = name.substring(2);
         }

         if (name.length() > 1)
         {
            return Character.toLowerCase(name.charAt(0)) + name.substring(1);
         }
         else
         {
            return Character.toString(Character.toLowerCase(name.charAt(0)));
         }
      }

      throw new IllegalArgumentException("Unknown annotation: " + annotation);
   }

   /**
    * Get the config-property-type for an annotation
    * @param annotation The annotation
    * @return The fully qualified classname
    * @exception ClassNotFoundException Thrown if a class cannot be found
    */
   @SuppressWarnings("unchecked")
   private String getConfigPropertyType(Annotation annotation)
      throws ClassNotFoundException
   {
      if (AnnotationType.FIELD.equals(annotation.getType()))
      {
         ClassLoader cl = SecurityActions.getThreadContextClassLoader();
         Class clz = Class.forName(annotation.getClassName(), true, cl);

         while (!Object.class.equals(clz))
         {
            try
            {
               Field field = clz.getDeclaredField(annotation.getMemberName());

               return field.getType().getName();
            }
            catch (NoSuchFieldException nsfe)
            {
               clz = clz.getSuperclass();
            }
         }
      }
      else if (AnnotationType.METHOD.equals(annotation.getType()))
      {
         ClassLoader cl = SecurityActions.getThreadContextClassLoader();
         Class clz = Class.forName(annotation.getClassName(), true, cl);

         Class[] parameters = null;

         if (annotation.getParameterTypes() != null)
         {
            parameters = new Class[annotation.getParameterTypes().length];

            for (int i = 0; i < annotation.getParameterTypes().length; i++)
            {
               String parameter = annotation.getParameterTypes()[i];
               parameters[i] = Class.forName(parameter, true, cl);
            }
         }

         while (!Object.class.equals(clz))
         {
            try
            {
               Method method = clz.getDeclaredMethod(annotation.getMemberName(), parameters);
        
               if (void.class.equals(method.getReturnType()))
               {
                  if (parameters != null && parameters.length > 0)
                  {
                     return parameters[0].getName();
                  }
               }
               else
               {
                  return method.getReturnType().getName();
               }
            }
            catch (NoSuchMethodException nsme)
            {
               clz = clz.getSuperclass();
            }
         }
      }

      throw new IllegalArgumentException("Unknown annotation: " + annotation);
   }
}
TOP

Related Classes of org.jboss.jca.common.annotations.Annotations

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.