View Javadoc

1   /*
2    * Copyright 2010 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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 org.kuali.rice.core.versions;
17  
18  import org.kuali.rice.core.versions.annotations.DeprecatedSince;
19  import org.kuali.rice.core.versions.annotations.SupportedSince;
20  
21  import java.lang.annotation.Annotation;
22  import java.lang.reflect.AnnotatedElement;
23  import java.lang.reflect.Field;
24  import java.lang.reflect.Method;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.List;
28  
29  public class VersionHelper {
30      public static boolean areVersionsCompatible(Object source, Object target) {
31          double sourceVer = getHighestVersion(source);
32          double targetVer = getHighestVersion(target);
33          return targetVer <= sourceVer;
34      }
35  
36      public static boolean isVersionCompatible(Object obj, double ver) {
37          return ver <= getHighestVersion(obj);
38      }
39  
40      public static double getHighestVersion(Object obj) {
41          // TODO: Could be more efficient using an Array Copy
42          Class clazz = obj.getClass();
43          Method[] methods = clazz.getMethods();
44          Field[] fields = clazz.getFields();
45          List<AnnotatedElement> elements;
46          elements = new ArrayList<AnnotatedElement>(methods.length + fields.length + 1);
47          elements.add(clazz);
48          elements.addAll(Arrays.asList(methods));
49          elements.addAll(Arrays.asList(fields));
50          return getHighestVersion(elements);
51      }
52  
53      protected static double getHighestVersion(List<AnnotatedElement> elements) {
54          double highestVersion = 1.0;
55          for ( AnnotatedElement element : elements ) {
56              DeprecatedSince deprecated = element.getAnnotation(DeprecatedSince.class);
57              SupportedSince supported = element.getAnnotation(SupportedSince.class);
58              double compareVersion = getHighestVersion(
59                      new Annotation[] {deprecated, supported});
60              if ( highestVersion < compareVersion )
61                  highestVersion = compareVersion;
62          }
63          return highestVersion;
64      }
65  
66      protected static double getHighestVersion(Annotation[] annotations) {
67          double highestVersion = 1.0;
68          for ( Annotation annotation : annotations ) {
69              double compareVersion = 1.0;
70              if ( annotation instanceof DeprecatedSince )
71                  compareVersion = ((DeprecatedSince)annotation).version();
72              else if ( annotation instanceof DeprecatedSince )
73                  compareVersion = ((SupportedSince)annotation).version();
74              if ( highestVersion < compareVersion )
75                  highestVersion = compareVersion;
76          }
77          return highestVersion;
78      }
79  
80      public static boolean isMethodSupported(Object obj, String methodName,
81                                              double ver) {
82          Method[] methods = obj.getClass().getMethods();
83          for ( Method method : methods ) {
84              if ( method.getName().equals(methodName) ) {
85                  // TODO: Do this better, prefer methods with annotations
86                  //       to those without
87                  return isMethodSupported(method, ver);
88              }
89          }
90          return false;
91      }
92  
93      public static boolean isMethodSupported(Method method, double ver) {
94          SupportedSince supported = method.getAnnotation(SupportedSince.class);
95          DeprecatedSince deprecated = method.getAnnotation(DeprecatedSince.class);
96          return isVersionValid(supported, deprecated, ver);
97      }
98  
99      public static boolean isFieldSupported(Object obj, String fieldName,
100                                            double ver) {
101         try {
102             Field field = obj.getClass().getField(fieldName);
103             return isFieldSupported(field, ver);
104         }
105         catch ( NoSuchFieldException e ) {
106             return false;
107         }
108     }
109 
110     public static boolean isFieldSupported(Field field, double ver) {
111         SupportedSince supported = field.getAnnotation(SupportedSince.class);
112         DeprecatedSince deprecated = field.getAnnotation(DeprecatedSince.class);
113         return isVersionValid(supported, deprecated, ver);
114     }
115 
116     public static boolean isClassSupported(Object obj, double ver) {
117         SupportedSince supported = obj.getClass().getAnnotation(SupportedSince.class);
118         DeprecatedSince deprecated = obj.getClass().getAnnotation(DeprecatedSince.class);
119         return isVersionValid(supported, deprecated, ver);
120     }
121 
122     protected static boolean isVersionValid(SupportedSince supported,
123                                             DeprecatedSince deprecated,
124                                             double ver) {
125         double supportedVersion = supported != null ? supported.version() : 1.0;
126         if ( supported == null || supported.version() <= ver )
127             return ( deprecated == null || ver < deprecated.version() );
128         else
129             return false;
130     }
131 }