Home » geronimo-2.2-source-release » org.apache.geronimo.gbean.annotation » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    *  http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.geronimo.gbean.annotation;
   21   
   22   import java.beans.Introspector;
   23   import java.lang.annotation.Annotation;
   24   import java.lang.reflect.Constructor;
   25   import java.lang.reflect.Method;
   26   import java.lang.reflect.ParameterizedType;
   27   import java.lang.reflect.Type;
   28   import java.lang.reflect.WildcardType;
   29   import java.util.Collection;
   30   import java.util.HashSet;
   31   import java.util.Set;
   32   
   33   import org.apache.geronimo.gbean.GBeanInfo;
   34   import org.apache.geronimo.gbean.GBeanInfoBuilder;
   35   import org.apache.geronimo.gbean.GReferenceInfo;
   36   
   37   
   38   
   39   
   40   /**
   41    *
   42    * @version $Rev:$ $Date:$
   43    */
   44   public class AnnotationGBeanInfoBuilder {
   45       private static final String DEFAULT_J2EE_TYPE = "GBean";
   46       
   47       private final Class gbeanClass;
   48       
   49       public AnnotationGBeanInfoBuilder(Class gbeanClass) {
   50           if (null == gbeanClass) {
   51               throw new IllegalArgumentException("gbeanClass is required");
   52           }
   53           this.gbeanClass = gbeanClass;
   54       }
   55   
   56       public GBeanInfo buildGBeanInfo() throws GBeanAnnotationException {
   57           String name = getName();
   58           String j2eeType = getJ2eeyType();
   59           GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(name, gbeanClass, j2eeType);
   60           
   61           setPriority(infoBuilder);
   62           setConstructor(infoBuilder);
   63           markPersistent(infoBuilder);
   64           addReferences(infoBuilder);
   65           
   66           return infoBuilder.getBeanInfo();
   67       }
   68       
   69       protected void setPriority(GBeanInfoBuilder infoBuilder) {
   70           Priority priority = (Priority) gbeanClass.getAnnotation(Priority.class);
   71           if (null == priority) {
   72               return;
   73           }
   74   
   75           infoBuilder.setPriority(priority.priority());
   76       }
   77   
   78       protected void setConstructor(GBeanInfoBuilder infoBuilder) {
   79           Constructor[] constructors = gbeanClass.getDeclaredConstructors();
   80           for (Constructor constructor : constructors) {
   81               Annotation[][] paramsAnnotations = constructor.getParameterAnnotations();
   82               if (0 < paramsAnnotations.length) {
   83                   Annotation[] paramAnnotations = paramsAnnotations[0];
   84                   for (Annotation paramAnnotation : paramAnnotations) {
   85                       if (paramAnnotation instanceof ParamAttribute 
   86                               || paramAnnotation instanceof ParamReference
   87                               || paramAnnotation instanceof ParamSpecial) {
   88                           setConstructor(infoBuilder, constructor);
   89                           return;
   90                       }
   91                   }
   92               }
   93           }
   94           
   95           try {
   96               gbeanClass.getConstructor();
   97           } catch (Exception e) {
   98               throw new GBeanAnnotationException("Missing default constructor");
   99           }
  100           infoBuilder.setConstructor(new String[0]);   
  101       }
  102   
  103       protected void setConstructor(GBeanInfoBuilder infoBuilder, Constructor constructor) {
  104           Class[] types = constructor.getParameterTypes();
  105           Type[] genericTypes = constructor.getGenericParameterTypes();
  106           Annotation[][] parametersAnnotations = constructor.getParameterAnnotations();
  107           String[] cstrNames = new String[types.length];
  108           int index = 0;
  109           for (Annotation[] paramterAnnotations : parametersAnnotations) {
  110               Class parameterType = types[index];
  111               boolean annotationFound = false;
  112               for (Annotation parameterAnnotation : paramterAnnotations) {
  113                   if (parameterAnnotation instanceof ParamAttribute) {
  114                       ParamAttribute attribute = (ParamAttribute) parameterAnnotation;
  115                       String name = attribute.name();
  116                       boolean persistent = attribute.persistent();
  117                       boolean manageable = attribute.manageable();
  118                       if (attribute.encrypted() == EncryptionSetting.ENCRYPTED) {
  119                           infoBuilder.addAttribute(name, parameterType,
  120                                   persistent, manageable, true);
  121                       } else if (attribute.encrypted() == EncryptionSetting.PLAINTEXT) {
  122                           infoBuilder.addAttribute(name, parameterType,
  123                                   persistent, manageable, false);
  124                       } else {
  125                           infoBuilder.addAttribute(name, parameterType,
  126                                   persistent, manageable);
  127                       }
  128                       cstrNames[index] = name;
  129                       annotationFound = true;
  130                       break;
  131                   } else if (parameterAnnotation instanceof ParamSpecial) {
  132                       ParamSpecial attribute = (ParamSpecial) parameterAnnotation;
  133                       String name = attribute.type().name();
  134                       infoBuilder.addAttribute(name, parameterType, false);
  135                       cstrNames[index] = name;
  136                       annotationFound = true;
  137                       break;
  138                   } else if (parameterAnnotation instanceof ParamReference) {
  139                       ParamReference reference = (ParamReference) parameterAnnotation;
  140                       String name = reference.name();
  141                       Class referenceType = getGenericActualType(genericTypes[index], parameterType);
  142                       String namingType = reference.namingType();
  143                       infoBuilder.addReference(name, referenceType, namingType);
  144                       cstrNames[index] = name;
  145                       annotationFound = true;
  146                       break;
  147                   }
  148               }
  149               if (!annotationFound) {
  150                   throw new GBeanAnnotationException("Missing constructor parameter annotation for constructor ["
  151                           + constructor + "] at index [" + index + "]");
  152               }
  153               index++;
  154           }
  155           infoBuilder.setConstructor(cstrNames);
  156       }
  157   
  158       protected Set<Method> filterSettersByAnnotation(Class annotationClass) {
  159           Set<Method> filteredMethods = new HashSet<Method>();
  160           Method[] methods = gbeanClass.getMethods();
  161           for (Method method : methods) {
  162               if (null == method.getAnnotation(annotationClass)) {
  163                   continue;
  164               }
  165               if (isNotSetter(method)) {
  166                   throw new GBeanAnnotationException("[" + method + "] is not a setter and annotated with ["
  167                           + annotationClass + "]");
  168               }
  169               filteredMethods.add(method);
  170           }  
  171           return filteredMethods;
  172       }
  173       
  174       protected void markPersistent(GBeanInfoBuilder infoBuilder) {
  175           Set<Method> methods = filterSettersByAnnotation(Persistent.class);
  176           for (Method method : methods) {
  177               Persistent persistent = method.getAnnotation(Persistent.class);
  178               Class type = method.getParameterTypes()[0];
  179               String name = getName(method);
  180               name = Introspector.decapitalize(name);
  181               if (persistent.encrypted() == EncryptionSetting.ENCRYPTED) {
  182                   infoBuilder.addAttribute(name, type, true, persistent.manageable(), true);
  183               } else if (persistent.encrypted() == EncryptionSetting.PLAINTEXT) {
  184                   infoBuilder.addAttribute(name, type, true, persistent.manageable(), false);
  185               } else {
  186                   infoBuilder.addAttribute(name, type, true, persistent.manageable());
  187               }
  188           }
  189       }
  190       
  191       protected void addReferences(GBeanInfoBuilder infoBuilder) {
  192           Set<Method> methods = filterSettersByAnnotation(Reference.class);
  193           for (Method method : methods) {
  194               Reference reference = method.getAnnotation(Reference.class);
  195               Class type = method.getParameterTypes()[0];
  196               Class referenceType = getGenericActualType(method.getGenericParameterTypes()[0], type);
  197               String name = getName(method);
  198               GReferenceInfo referenceInfo = new GReferenceInfo(name, 
  199                   referenceType.getName(), 
  200                   type.getName(), 
  201                   method.getName(), 
  202                   reference.namingType());
  203               infoBuilder.addReference(referenceInfo);
  204           }
  205       }
  206       
  207       protected Class getGenericActualType(Type genericType, Class parameterType) {
  208           if (Collection.class.isAssignableFrom(parameterType)) {
  209               if (genericType instanceof ParameterizedType) {
  210                   ParameterizedType parameterizedType = (ParameterizedType) genericType;
  211                   Type componentType = parameterizedType.getActualTypeArguments()[0];
  212                   if (componentType instanceof Class) {
  213                       return (Class) componentType;
  214                   }
  215                   if (componentType instanceof WildcardType) {
  216                       Type[] upper = ((WildcardType)componentType).getUpperBounds();
  217                       if (upper.length == 1 && upper[0] instanceof Class) {
  218                           return (Class) upper[0];
  219                       }
  220                   }
  221                   throw new GBeanAnnotationException("Generic type is not a class: " + componentType);
  222               } else {
  223                   throw new GBeanAnnotationException(Collection.class + " parameter must be generified");
  224               }
  225           }
  226           return parameterType;
  227       }
  228       
  229       protected String getName() {
  230           GBean bean = (GBean) gbeanClass.getAnnotation(GBean.class);
  231           if (null == bean) {
  232               return gbeanClass.getSimpleName();
  233           }
  234           String name = bean.name();
  235           if (name.equals("")) {
  236               name = gbeanClass.getSimpleName();
  237           }
  238           return name;
  239       }
  240   
  241       protected String getJ2eeyType() {
  242           GBean bean = (GBean) gbeanClass.getAnnotation(GBean.class);
  243           if (null == bean) {
  244               return DEFAULT_J2EE_TYPE;
  245           }
  246           return bean.j2eeType();
  247       }
  248   
  249       protected String getName(Method method) {
  250           return method.getName().substring(3);
  251       }
  252   
  253       protected boolean isNotSetter(Method method) {
  254           return !(method.getName().startsWith("set") && method.getParameterTypes().length == 1);
  255       }
  256   
  257   }

Home » geronimo-2.2-source-release » org.apache.geronimo.gbean.annotation » [javadoc | source]