Coverage Report - de.smartics.properties.spi.core.metadata.PropertyMetaDataParser
 
Classes in this File Line Coverage Branch Coverage Complexity
PropertyMetaDataParser
0%
0/207
0%
0/84
2.562
 
 1  
 /*
 2  
  * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package de.smartics.properties.spi.core.metadata;
 17  
 
 18  
 import static de.smartics.util.lang.StaticAnalysis.RAWTYPES;
 19  
 import static de.smartics.util.lang.StaticAnalysis.UNCHECKED;
 20  
 
 21  
 import java.lang.annotation.Annotation;
 22  
 import java.lang.reflect.Method;
 23  
 import java.util.ArrayList;
 24  
 import java.util.Collection;
 25  
 import java.util.List;
 26  
 
 27  
 import javax.validation.constraints.Size;
 28  
 
 29  
 import org.apache.commons.lang.ArrayUtils;
 30  
 
 31  
 import de.smartics.properties.api.core.annotations.AccessType;
 32  
 import de.smartics.properties.api.core.annotations.PropertyDefinitionTime;
 33  
 import de.smartics.properties.api.core.annotations.PropertyElementType;
 34  
 import de.smartics.properties.api.core.annotations.PropertyListElementConstraints;
 35  
 import de.smartics.properties.api.core.annotations.PropertySet;
 36  
 import de.smartics.properties.api.core.annotations.PropertyUse.UseType;
 37  
 import de.smartics.properties.api.core.annotations.PropertyValueSecured;
 38  
 import de.smartics.properties.api.core.domain.PropertiesContext;
 39  
 import de.smartics.properties.api.core.domain.PropertyCategories;
 40  
 import de.smartics.properties.api.core.domain.PropertyConstraint;
 41  
 import de.smartics.properties.api.core.domain.PropertyDescriptor;
 42  
 import de.smartics.properties.api.core.domain.PropertyExpression;
 43  
 import de.smartics.properties.api.core.domain.PropertyKey;
 44  
 import de.smartics.properties.api.core.domain.PropertyType;
 45  
 import de.smartics.properties.api.core.domain.PropertyValueRange;
 46  
 import de.smartics.properties.spi.core.constraint.jsr303.GenericPropertyConstraint;
 47  
 import de.smartics.properties.spi.core.constraints.ListValueConstraint;
 48  
 import de.smartics.properties.spi.core.constraints.PropertyRangeConstraint;
 49  
 import de.smartics.properties.spi.core.context.PropertyContextProxy;
 50  
 import de.smartics.properties.spi.core.metadata.PropertyMetaData.Builder;
 51  
 import de.smartics.properties.spi.core.util.PropertyUtils;
 52  
 import de.smartics.properties.spi.core.value.CollectionPropertyValueRange;
 53  
 import de.smartics.properties.spi.core.value.EnumeratedPropertyValueRange;
 54  
 import de.smartics.util.lang.Arg;
 55  
 
 56  
 /**
 57  
  * Parses runtime annotations to create property metadata.
 58  
  */
 59  
 public final class PropertyMetaDataParser
 60  
 { // NOPMD
 61  
   // ********************************* Fields *********************************
 62  
 
 63  
   // --- constants ------------------------------------------------------------
 64  
 
 65  
   // --- members --------------------------------------------------------------
 66  
 
 67  
   /**
 68  
    * The context to access property metadata.
 69  
    */
 70  
   private final PropertiesContext context;
 71  
 
 72  
   // ****************************** Initializer *******************************
 73  
 
 74  
   // ****************************** Constructors ******************************
 75  
 
 76  
   /**
 77  
    * Default constructor to generate property descriptors with comments.
 78  
    *
 79  
    * @param context the context to access property metadata. May be
 80  
    *          <code>null</code> in which case no comments are generated.
 81  
    */
 82  
   private PropertyMetaDataParser(final PropertiesContext context)
 83  0
   {
 84  0
     this.context = context;
 85  0
   }
 86  
 
 87  
   // ****************************** Inner Classes *****************************
 88  
 
 89  
   // ********************************* Methods ********************************
 90  
 
 91  
   // --- init -----------------------------------------------------------------
 92  
 
 93  
   // --- factory --------------------------------------------------------------
 94  
 
 95  
   /**
 96  
    * Convenience constructor to generate property descriptors without comments.
 97  
    *
 98  
    * @return the created parser instance.
 99  
    */
 100  
   public static PropertyMetaDataParser createWithoutContextAccess()
 101  
   {
 102  0
     return new PropertyMetaDataParser(null);
 103  
   }
 104  
 
 105  
   /**
 106  
    * Convenience constructor to generate property descriptors with access to
 107  
    * property comments.
 108  
    *
 109  
    * @param context the context to access comment information for properties.
 110  
    * @return the created parser instance.
 111  
    * @throws NullPointerException if {@code context} is <code>null</code>.
 112  
    */
 113  
   public static PropertyMetaDataParser create(final PropertiesContext context)
 114  
     throws NullPointerException
 115  
   {
 116  0
     Arg.checkNotNull("context", context);
 117  0
     return new PropertyMetaDataParser(context);
 118  
   }
 119  
 
 120  
   // --- get&set --------------------------------------------------------------
 121  
 
 122  
   // --- business -------------------------------------------------------------
 123  
 
 124  
   /**
 125  
    * Reads the property descriptor information from the type.
 126  
    *
 127  
    * @param propertySetType the type to read the property descriptor.
 128  
    * @return the property descriptor provided by the methods of the type.
 129  
    * @throws NullPointerException if {@code propertySetType} is
 130  
    *           <code>null</code>.
 131  
    * @throws IllegalArgumentException if {@code propertySetType} is not
 132  
    *           annotated with {@link PropertySet}.
 133  
    */
 134  
   public List<PropertyDescriptor> readDescriptors(final Class<?> propertySetType)
 135  
     throws NullPointerException, IllegalArgumentException
 136  
   {
 137  0
     Arg.checkNotNull("propertySetType", propertySetType);
 138  0
     PropertyUtils.checkPropertySetType(propertySetType);
 139  
 
 140  0
     final Method[] methods = propertySetType.getMethods();
 141  0
     final List<PropertyDescriptor> descriptors =
 142  
         new ArrayList<PropertyDescriptor>(methods.length);
 143  0
     for (final Method method : methods)
 144  
     {
 145  0
       if (PropertyUtils.isPropertyMethod(method))
 146  
       {
 147  0
         final PropertyDescriptor descriptor = readDescriptor(method);
 148  0
         descriptors.add(descriptor);
 149  
       }
 150  
     }
 151  
 
 152  0
     return descriptors;
 153  
   }
 154  
 
 155  
   /**
 156  
    * Reads the property descriptor information from the method.
 157  
    *
 158  
    * @param method the method to read the property descriptor.
 159  
    * @return the property descriptor provided by this method.
 160  
    * @throws NullPointerException if {@code method} is <code>null</code>.
 161  
    */
 162  
   public PropertyDescriptor readDescriptor(final Method method)
 163  
     throws NullPointerException
 164  
   {
 165  0
     Arg.checkNotNull("method", method);
 166  
 
 167  0
     final PropertyMetaData.Builder builder = new PropertyMetaData.Builder();
 168  
 
 169  0
     final Class<?> declaringType = method.getDeclaringClass();
 170  0
     final PropertyKey key = readKey(method);
 171  0
     final PropertyType type = readType(method);
 172  0
     builder.with(new PropertyContextProxy(context))
 173  
         .withDeclaringType(declaringType).with(key).with(type);
 174  
 
 175  0
     addValueRange(builder, method);
 176  0
     addExpression(builder, method);
 177  0
     addLifecycle(builder, method);
 178  0
     addConstraints(builder, method);
 179  0
     addDocumentProxy(builder, method, key);
 180  0
     addComments(builder);
 181  0
     addSecured(builder, method);
 182  0
     addCategories(builder, method);
 183  0
     addUseType(builder, method);
 184  
 
 185  0
     return builder.build();
 186  
   }
 187  
 
 188  
   private static void addSecured(final Builder builder, final Method method)
 189  
   {
 190  0
     final boolean secured = readSecured(method);
 191  0
     builder.setSecured(secured);
 192  0
   }
 193  
 
 194  
   private static boolean readSecured(final Method method)
 195  
   {
 196  0
     final PropertyValueSecured secured =
 197  
         method.getAnnotation(PropertyValueSecured.class);
 198  
     final boolean value;
 199  0
     if (secured != null)
 200  
     {
 201  0
       value = secured.decrypt();
 202  
     }
 203  
     else
 204  
     {
 205  0
       value = false;
 206  
     }
 207  0
     return value;
 208  
   }
 209  
 
 210  
   /**
 211  
    * Reads the property key information from the method.
 212  
    *
 213  
    * @param method the method to read the property key.
 214  
    * @return the property key provided by this method.
 215  
    */
 216  
   public PropertyKey readKey(final Method method)
 217  
   {
 218  0
     final String set = readPropertySetName(method);
 219  0
     final String name = readPropertyKeyName(method);
 220  0
     return PropertyKey.create(set, name);
 221  
   }
 222  
 
 223  
   /**
 224  
    * Reads the property set name of the type.
 225  
    *
 226  
    * @param type the type to read the property set name.
 227  
    * @return the property name as specified of defaulted.
 228  
    */
 229  
   public String readPropertySetName(final Class<?> type)
 230  
   {
 231  0
     String propertySetName = readPropertySetNameInternal(type);
 232  
 
 233  0
     if (" ".equals(propertySetName))
 234  
     {
 235  0
       propertySetName = type.getName();
 236  
     }
 237  0
     else if ("".equals(propertySetName))
 238  
     {
 239  0
       propertySetName = null;
 240  
     }
 241  
 
 242  0
     return propertySetName;
 243  
   }
 244  
 
 245  
   private static String readPropertyKeyName(final Method method)
 246  
   {
 247  
     final String keyName;
 248  
 
 249  0
     final de.smartics.properties.api.core.annotations.PropertyKeyName propertyKey =
 250  
         method
 251  
             .getAnnotation(de.smartics.properties.api.core.annotations.PropertyKeyName.class);
 252  0
     if (propertyKey != null)
 253  
     {
 254  0
       keyName = propertyKey.value();
 255  
     }
 256  
     else
 257  
     {
 258  0
       final String methodName = method.getName();
 259  0
       if (isGetterMethod(methodName))
 260  
       {
 261  0
         keyName = calcPropertyName(methodName);
 262  
       }
 263  
       else
 264  
       {
 265  0
         keyName = methodName;
 266  
       }
 267  
     }
 268  
 
 269  0
     return keyName;
 270  
   }
 271  
 
 272  
   private static String calcPropertyName(final String methodName)
 273  
   {
 274  0
     return Character.toLowerCase(methodName.charAt(3))
 275  
            + methodName.substring(4);
 276  
   }
 277  
 
 278  
   private static boolean isGetterMethod(final String methodName)
 279  
   {
 280  0
     return methodName.length() > 3 && methodName.startsWith("get")
 281  
            && Character.isUpperCase(methodName.charAt(3));
 282  
   }
 283  
 
 284  
   private static String readPropertySetName(final Method method)
 285  
   {
 286  
     final String propertySetName;
 287  
 
 288  0
     final PropertySet primaryPropertySet =
 289  
         method.getAnnotation(PropertySet.class);
 290  0
     if (primaryPropertySet != null)
 291  
     {
 292  0
       propertySetName = primaryPropertySet.value();
 293  
     }
 294  
     else
 295  
     {
 296  0
       final Class<?> type = method.getDeclaringClass();
 297  0
       propertySetName = readPropertySetNameInternal(type);
 298  
     }
 299  
 
 300  0
     if (" ".equals(propertySetName))
 301  
     {
 302  0
       final Class<?> type = method.getDeclaringClass();
 303  0
       return type.getName();
 304  
     }
 305  0
     else if ("".equals(propertySetName))
 306  
     {
 307  0
       return null;
 308  
     }
 309  
 
 310  0
     return propertySetName;
 311  
   }
 312  
 
 313  
   private static String readPropertySetNameInternal(final Class<?> type)
 314  
   {
 315  
     final String propertySetName;
 316  0
     final PropertySet propertySet = type.getAnnotation(PropertySet.class);
 317  0
     if (propertySet != null)
 318  
     {
 319  0
       propertySetName = propertySet.value();
 320  
     }
 321  
     else
 322  
     {
 323  0
       propertySetName = type.getName();
 324  
     }
 325  0
     return propertySetName;
 326  
   }
 327  
 
 328  
   private static PropertyType readType(final Method method)
 329  
   {
 330  0
     final Class<?> type = method.getReturnType();
 331  0
     final Class<?> subType = determineSubType(method);
 332  
 
 333  0
     return new PropertyType(type, subType);
 334  
   }
 335  
 
 336  
   private static Class<?> determineSubType(final Method method)
 337  
   {
 338  0
     final PropertyElementType elementType =
 339  
         method.getAnnotation(PropertyElementType.class);
 340  
     final Class<?> subType;
 341  0
     if (elementType != null)
 342  
     {
 343  0
       subType = elementType.value();
 344  
     }
 345  
     else
 346  
     {
 347  0
       subType = null;
 348  
     }
 349  0
     return subType;
 350  
   }
 351  
 
 352  
   @SuppressWarnings({ RAWTYPES, UNCHECKED })
 353  
   private static void addValueRange(final Builder builder, final Method method)
 354  
   {
 355  0
     final PropertyValueRange<?> valueRange = calculateValueRange(method);
 356  0
     if (valueRange != null)
 357  
     {
 358  0
       builder.with(valueRange);
 359  0
       final PropertyRangeConstraint<?> constraint =
 360  
           new PropertyRangeConstraint(valueRange);
 361  0
       builder.add(constraint);
 362  
     }
 363  0
   }
 364  
 
 365  
   @SuppressWarnings({ RAWTYPES, UNCHECKED })
 366  
   private static PropertyValueRange<?> calculateValueRange(final Method method)
 367  
   {
 368  0
     final Class<?> returnType = method.getReturnType();
 369  0
     if (returnType.isEnum())
 370  
     {
 371  0
       final PropertyValueRange<?> valueRange =
 372  
           new EnumeratedPropertyValueRange(returnType);
 373  0
       return valueRange;
 374  
     }
 375  
     else
 376  
     {
 377  0
       final de.smartics.properties.api.core.annotations.PropertyIntValueRange intAnnotation =
 378  
           method
 379  
               .getAnnotation(de.smartics.properties.api.core.annotations.PropertyIntValueRange.class);
 380  0
       if (intAnnotation != null)
 381  
       {
 382  0
         final Integer[] values = ArrayUtils.toObject(intAnnotation.value());
 383  0
         final CollectionPropertyValueRange<Integer> valueRange =
 384  
             new CollectionPropertyValueRange<Integer>(values);
 385  0
         return valueRange;
 386  
       }
 387  
 
 388  0
       final de.smartics.properties.api.core.annotations.PropertyStringValueRange annotation =
 389  
           method
 390  
               .getAnnotation(de.smartics.properties.api.core.annotations.PropertyStringValueRange.class);
 391  0
       if (annotation != null)
 392  
       {
 393  0
         final String[] values = annotation.value();
 394  0
         final CollectionPropertyValueRange<String> valueRange =
 395  
             new CollectionPropertyValueRange<String>(values);
 396  0
         return valueRange;
 397  
       }
 398  
     }
 399  
 
 400  0
     return null;
 401  
   }
 402  
 
 403  
   private static void addExpression(final Builder builder, final Method method)
 404  
   {
 405  0
     final de.smartics.properties.api.core.annotations.PropertyExpression annotation =
 406  
         method
 407  
             .getAnnotation(de.smartics.properties.api.core.annotations.PropertyExpression.class);
 408  0
     if (annotation != null)
 409  
     {
 410  0
       final String expressionString = annotation.value();
 411  0
       final PropertyExpression expression =
 412  
           PropertyExpression.create(expressionString);
 413  0
       builder.with(expression);
 414  
     }
 415  0
   }
 416  
 
 417  
   private void addLifecycle(final Builder builder, final Method method)
 418  
   {
 419  0
     final de.smartics.properties.api.core.annotations.PropertyLifecycle annotation =
 420  
         method
 421  
             .getAnnotation(de.smartics.properties.api.core.annotations.PropertyLifecycle.class);
 422  0
     if (annotation != null)
 423  
     {
 424  0
       final PropertyDefinitionTime configurationTime =
 425  
           annotation.definitionTime();
 426  0
       if (configurationTime != null)
 427  
       {
 428  0
         builder.with(configurationTime);
 429  
       }
 430  
 
 431  0
       final AccessType accessType = annotation.access();
 432  0
       if (accessType != null)
 433  
       {
 434  0
         builder.with(accessType);
 435  
       }
 436  
 
 437  0
       final long updateInterval = annotation.updateInterval();
 438  0
       builder.withUpdateIntervalInMs(updateInterval);
 439  
     }
 440  0
   }
 441  
 
 442  
   @SuppressWarnings({ RAWTYPES, UNCHECKED })
 443  
   private void addConstraints(final Builder builder, final Method method)
 444  
   {
 445  0
     final Annotation[] annotations = method.getAnnotations();
 446  0
     boolean collectionConstraintAdded = false;
 447  
 
 448  0
     for (final Annotation annotation : annotations)
 449  
     {
 450  0
       final javax.validation.Constraint annotationAnnotation =
 451  
           annotation.annotationType().getAnnotation(
 452  
               javax.validation.Constraint.class);
 453  0
       if (annotationAnnotation != null)
 454  
       {
 455  0
         if (annotation.annotationType() != Size.class)
 456  
         {
 457  0
           final GenericPropertyConstraint propertyConstraint =
 458  
               new GenericPropertyConstraint(annotation, method.getReturnType());
 459  0
           builder.add(propertyConstraint);
 460  0
         }
 461  
         else
 462  
         {
 463  0
           checkCollection(builder, method, (Size) annotation);
 464  0
           collectionConstraintAdded = true;
 465  
         }
 466  
       }
 467  
     }
 468  
 
 469  0
     if (!collectionConstraintAdded)
 470  
     {
 471  0
       checkCollection(builder, method, null);
 472  
     }
 473  0
   }
 474  
 
 475  
   private void checkCollection(final PropertyMetaData.Builder builder,
 476  
       final Method method, final Size size)
 477  
   {
 478  0
     final Class<?> type = builder.getType().getType();
 479  
 
 480  0
     if (Collection.class.isAssignableFrom(type))
 481  
     {
 482  0
       final PropertyElementType elementTypeAnnotation =
 483  
           method.getAnnotation(PropertyElementType.class);
 484  
 
 485  0
       final Class<?> elementType = calcElementType(elementTypeAnnotation);
 486  0
       final List<? extends PropertyConstraint<?>> elementConstraints =
 487  
           calcElementConstraints(method);
 488  0
       Integer min = null;
 489  0
       Integer max = null;
 490  0
       if (size != null)
 491  
       {
 492  0
         min = size.min();
 493  0
         max = size.max();
 494  
       }
 495  
 
 496  0
       final PropertyConstraint<?> propertyConstraint =
 497  
           new ListValueConstraint(elementType, min, max, elementConstraints);
 498  0
       builder.add(propertyConstraint);
 499  
     }
 500  0
   }
 501  
 
 502  
   private Class<?> calcElementType(
 503  
       final PropertyElementType elementTypeAnnotation)
 504  
   {
 505  
     final Class<?> elementType;
 506  0
     if (elementTypeAnnotation != null)
 507  
     {
 508  0
       elementType = elementTypeAnnotation.value();
 509  
     }
 510  
     else
 511  
     {
 512  0
       elementType = String.class;
 513  
     }
 514  0
     return elementType;
 515  
   }
 516  
 
 517  
   @SuppressWarnings({ RAWTYPES, UNCHECKED })
 518  
   private List<? extends PropertyConstraint<?>> calcElementConstraints(
 519  
       final Method method)
 520  
   {
 521  0
     final Annotation[] annotations = calcElementsConstraintsType(method);
 522  0
     if (annotations != null)
 523  
     {
 524  0
       final List constraints = new ArrayList(annotations.length);
 525  
 
 526  0
       for (final Annotation annotation : annotations)
 527  
       {
 528  0
         final javax.validation.Constraint annotationAnnotation =
 529  
             annotation.annotationType().getAnnotation(
 530  
                 javax.validation.Constraint.class);
 531  0
         if (annotationAnnotation != null)
 532  
         {
 533  0
           final GenericPropertyConstraint propertyConstraint =
 534  
               new GenericPropertyConstraint(annotation, method.getReturnType()); // FIXME:
 535  
                                                                                  // ===????
 536  0
           constraints.add(propertyConstraint);
 537  
         }
 538  
       }
 539  
 
 540  0
       return constraints;
 541  
     }
 542  
 
 543  0
     return new ArrayList(0);
 544  
   }
 545  
 
 546  
   private static Annotation[] calcElementsConstraintsType(final Method method) // NOPMD
 547  
   {
 548  0
     final Class<?> enclosingType = method.getDeclaringClass();
 549  0
     final Class<?>[] nestedClasses = enclosingType.getDeclaredClasses();
 550  0
     if (nestedClasses != null)
 551  
     {
 552  0
       for (final Class<?> nestedClass : nestedClasses)
 553  
       {
 554  0
         final PropertyListElementConstraints constraintsType =
 555  
             nestedClass.getAnnotation(PropertyListElementConstraints.class);
 556  0
         if (constraintsType != null)
 557  
         {
 558  0
           final String methodName = method.getName();
 559  0
           return calcElementConstraintMethod(nestedClass, methodName);
 560  
         }
 561  
       }
 562  
     }
 563  
 
 564  0
     return null;
 565  
   }
 566  
 
 567  
   private static Annotation[] calcElementConstraintMethod(
 568  
       final Class<?> nestedClass, final String methodName)
 569  
   {
 570  
     try
 571  
     {
 572  0
       final Method elementConstraintMethod =
 573  
           nestedClass.getMethod(methodName, new Class<?>[0]);
 574  0
       return elementConstraintMethod.getAnnotations();
 575  
     }
 576  0
     catch (final Exception e)
 577  
     {
 578  0
       return null;
 579  
     }
 580  
   }
 581  
 
 582  
   private void addDocumentProxy(final Builder builder, final Method method,
 583  
       final PropertyKey key)
 584  
   {
 585  0
     final DocumentMetaDataProxy proxy =
 586  
         new MetaInfDocumentMetaDataProxy(key, context, method);
 587  0
     builder.with(proxy);
 588  0
   }
 589  
 
 590  
   private void addComments(final Builder builder)
 591  
   {
 592  0
     final PropertyCommentProxy commentProxy = new PropertyCommentProxy(context);
 593  0
     builder.with(commentProxy);
 594  0
   }
 595  
 
 596  
   private void addCategories(final Builder builder, final Method method)
 597  
   {
 598  0
     final List<Class<?>> categories = readCategories(method);
 599  0
     if (!categories.isEmpty())
 600  
     {
 601  0
       final PropertyCategories.Builder catBuilder =
 602  
           new PropertyCategories.Builder();
 603  0
       for (final Class<?> category : categories)
 604  
       {
 605  0
         catBuilder.with(category);
 606  
       }
 607  0
       final PropertyCategories propertyCategories = catBuilder.build();
 608  0
       builder.with(propertyCategories);
 609  
     }
 610  0
   }
 611  
 
 612  
   private static List<Class<?>> readCategories(final Method method)
 613  
   {
 614  0
     final List<Class<?>> categories = new ArrayList<Class<?>>();
 615  
 
 616  0
     final de.smartics.properties.api.core.annotations.PropertyCategories methodAnnotation =
 617  
         method
 618  
             .getAnnotation(de.smartics.properties.api.core.annotations.PropertyCategories.class);
 619  0
     addCategoriesFromAnnotation(categories, methodAnnotation);
 620  
 
 621  0
     final Class<?> type = method.getDeclaringClass();
 622  0
     final de.smartics.properties.api.core.annotations.PropertyCategories typeAnnotation =
 623  
         type.getAnnotation(de.smartics.properties.api.core.annotations.PropertyCategories.class);
 624  0
     addCategoriesFromAnnotation(categories, typeAnnotation);
 625  
 
 626  0
     return categories;
 627  
   }
 628  
 
 629  
   private static void addCategoriesFromAnnotation(
 630  
       final List<Class<?>> categories,
 631  
       final de.smartics.properties.api.core.annotations.PropertyCategories typeAnnotation)
 632  
   {
 633  0
     if (typeAnnotation != null)
 634  
     {
 635  0
       final Class<?>[] categoryTypes = typeAnnotation.value();
 636  0
       for (final Class<?> categoryType : categoryTypes)
 637  
       {
 638  0
         categories.add(categoryType);
 639  
       }
 640  
     }
 641  0
   }
 642  
 
 643  
   private void addUseType(final Builder builder, final Method method)
 644  
   {
 645  0
     final Class<?> type = method.getDeclaringClass();
 646  0
     final de.smartics.properties.api.core.annotations.PropertyUse typeAnnotation =
 647  
         type.getAnnotation(de.smartics.properties.api.core.annotations.PropertyUse.class);
 648  0
     if (typeAnnotation != null)
 649  
     {
 650  0
       final UseType useType = typeAnnotation.value();
 651  0
       if (useType != null)
 652  
       {
 653  0
         builder.with(useType);
 654  
       }
 655  
     }
 656  0
   }
 657  
 
 658  
   // --- object basics --------------------------------------------------------
 659  
 
 660  
 }