View Javadoc
1   package com.atlassian.activeobjects;
2   
3   import com.atlassian.activeobjects.external.IgnoreReservedKeyword;
4   import com.atlassian.plugin.PluginException;
5   import com.google.common.base.Predicate;
6   import com.google.common.collect.ImmutableSet;
7   import net.java.ao.ActiveObjectsException;
8   import net.java.ao.Common;
9   import net.java.ao.Polymorphic;
10  import net.java.ao.RawEntity;
11  import net.java.ao.schema.FieldNameConverter;
12  import net.java.ao.schema.Ignore;
13  import net.java.ao.schema.NameConverters;
14  import net.java.ao.schema.TableNameConverter;
15  import org.slf4j.Logger;
16  import org.slf4j.LoggerFactory;
17  
18  import java.lang.reflect.Method;
19  import java.util.Set;
20  
21  import static com.google.common.collect.Iterables.any;
22  
23  public final class NamesLengthAndOracleReservedWordsEntitiesValidator implements EntitiesValidator {
24      static final Set<String> RESERVED_WORDS = ImmutableSet.of("BLOB", "CLOB", "NUMBER", "ROWID", "TIMESTAMP", "VARCHAR2");
25      static final int MAX_NUMBER_OF_ENTITIES = 200;
26  
27      private final Logger logger = LoggerFactory.getLogger(this.getClass());
28  
29      @Override
30      public Set<Class<? extends RawEntity<?>>> check(Set<Class<? extends RawEntity<?>>> entityClasses, NameConverters nameConverters) {
31          if (entityClasses.size() > MAX_NUMBER_OF_ENTITIES) {
32              throw new PluginException("Plugins are allowed no more than " + MAX_NUMBER_OF_ENTITIES + " entities!");
33          }
34          for (Class<? extends RawEntity<?>> entityClass : entityClasses) {
35              check(entityClass, nameConverters);
36          }
37          return entityClasses;
38      }
39  
40      void check(Class<? extends RawEntity<?>> entityClass, NameConverters nameConverters) {
41          checkTableName(entityClass, nameConverters.getTableNameConverter());
42  
43          final FieldNameConverter fieldNameConverter = nameConverters.getFieldNameConverter();
44          for (Method method : entityClass.getMethods()) {
45              checkColumnName(method, fieldNameConverter);
46              checkPolymorphicColumnName(method, fieldNameConverter);
47          }
48      }
49  
50      void checkTableName(Class<? extends RawEntity<?>> entityClass, TableNameConverter tableNameConverter) {
51          final String tableName = tableNameConverter.getName(entityClass);// will throw an exception if the entity name is too long
52          if (isReservedWord(tableName)) {
53              throw new ActiveObjectsException("Entity class' '" + entityClass.getName() + "' table name is " + tableName + " which is a reserved word!");
54          }
55      }
56  
57      void checkColumnName(Method method, FieldNameConverter fieldNameConverter) {
58          if ((Common.isAccessor(method) || Common.isMutator(method)) && !method.isAnnotationPresent(Ignore.class)) {
59              final String columnName = fieldNameConverter.getName(method);
60              if (isReservedWord(columnName)) {
61                  if (method.isAnnotationPresent(IgnoreReservedKeyword.class)) {
62                      logger.warn("Method " + method + " is annotated with " + IgnoreReservedKeyword.class.getName() + ", it may cause issue on Oracle. " +
63                              "You should change this column name to a non-reserved keyword! "
64                              + "The list of reserved keywords is the following: " + RESERVED_WORDS);
65                  } else {
66                      throw new ActiveObjectsException("Method '" + method + "' column name is " + columnName + " which is a reserved word!");
67                  }
68              }
69          }
70      }
71  
72      private boolean isReservedWord(final String name) {
73          return any(RESERVED_WORDS, new Predicate<String>() {
74              @Override
75              public boolean apply(String reservedWord) {
76                  return reservedWord.equalsIgnoreCase(name);
77              }
78          });
79      }
80  
81      void checkPolymorphicColumnName(Method method, FieldNameConverter fieldNameConverter) {
82          final Class<?> attributeTypeFromMethod = Common.getAttributeTypeFromMethod(method);
83          if (attributeTypeFromMethod != null && attributeTypeFromMethod.isAnnotationPresent(Polymorphic.class)) {
84              final String polyTypeName = fieldNameConverter.getPolyTypeName(method);
85              if (isReservedWord(polyTypeName)) {
86                  throw new ActiveObjectsException("Method '" + method + "' polymorphic column name is " + polyTypeName + " which is a reserved word!");
87              }
88          }
89      }
90  }