View Javadoc
1   package xuml.tools.model.compiler;
2   
3   import static com.google.common.collect.Maps.newHashMap;
4   
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.InputStreamReader;
8   import java.math.BigInteger;
9   import java.util.Map;
10  import java.util.Set;
11  
12  import com.google.common.base.Preconditions;
13  import com.google.common.collect.BiMap;
14  import com.google.common.collect.HashBiMap;
15  import com.google.common.collect.Sets;
16  import com.google.common.io.CharStreams;
17  
18  public class NameManager {
19  
20      private static NameManager instance;
21  
22      private Set<String> reservedWords;
23  
24      // Class -> (OtherClass+RNum/ThisClass+FieldName<->FieldName)
25      private final Map<String, BiMap<String, String>> referenceFields = newHashMap();
26  
27      private final Map<String, BiMap<String, String>> referencedColumns = newHashMap();
28  
29      private final Map<String, BiMap<String, String>> referencedTables = newHashMap();
30  
31      public NameManager() {
32          try {
33              reservedWords = Sets.newHashSet();
34              // the list below was obtained from http://drupal.org/node/141051
35              // and is a combination of sql reserved words from the following
36              // standards/databases:
37              // ANSI SQL 92, ANS SQL 99, ANSI SQL 2003, MySQL 3.23.x, MySQL 4.x,
38              // MySQL 5.x, PostGreSQL 8.1, MS SQL Server 2000, MS ODBC, Oracle
39              // 10.2
40              InputStream in = NameManager.class.getResourceAsStream("/database-reserved-words.txt");
41              Preconditions.checkNotNull(in, "reserved words not found!");
42              for (String line : CharStreams.readLines(new InputStreamReader(in))) {
43                  reservedWords.add(line.trim().toUpperCase());
44              }
45          } catch (IOException e) {
46              throw new RuntimeException(e);
47          }
48      }
49  
50      public synchronized static NameManager getInstance() {
51          if (null == instance) {
52              instance = new NameManager();
53          }
54          return instance;
55      }
56  
57      public String toFieldName(String cls, String viewedClass, BigInteger rNum) {
58          if (referenceFields.get(cls) == null) {
59              BiMap<String, String> bimap = HashBiMap.create();
60              referenceFields.put(cls, bimap);
61          }
62          BiMap<String, String> map = referenceFields.get(cls);
63          String key = getKey(viewedClass, rNum);
64          if (map.get(key) != null)
65              return map.get(key);
66          else {
67              String optimalFieldName = Util.lowerFirst(Util.toJavaIdentifier(viewedClass)) + "_R"
68                      + rNum;
69              String currentKey = map.inverse().get(optimalFieldName);
70              String fieldName;
71              if (currentKey == null)
72                  fieldName = optimalFieldName;
73              else
74                  fieldName = optimalFieldName + "_R" + rNum;
75              map.put(key, fieldName);
76              return fieldName;
77          }
78      }
79  
80      public String toFieldName(String cls, String attributeName) {
81          if (referenceFields.get(cls) == null) {
82              BiMap<String, String> bimap = HashBiMap.create();
83              referenceFields.put(cls, bimap);
84          }
85          BiMap<String, String> map = referenceFields.get(cls);
86          String key = getKey(cls, attributeName);
87          if (map.get(key) != null)
88              return map.get(key);
89          else {
90              String optimalFieldName = Util.lowerFirst(Util.toJavaIdentifier(attributeName));
91              String fieldName = optimalFieldName;
92              if (map.inverse().get(fieldName) != null) {
93                  int i = 1;
94                  while (map.inverse().get(fieldName + i) != null) {
95                      i++;
96                  }
97                  fieldName = fieldName + i;
98              }
99              map.put(key, fieldName);
100             return fieldName;
101         }
102     }
103 
104     public String toColumnName(String cls, String attributeName) {
105         if (referencedColumns.get(cls) == null) {
106             BiMap<String, String> bimap = HashBiMap.create();
107             referencedColumns.put(cls, bimap);
108         }
109         BiMap<String, String> map = referencedColumns.get(cls);
110         String key = getKey(cls, attributeName);
111         if (map.get(key) != null)
112             return map.get(key);
113         else {
114             String optimalColumnName = Util.lowerFirst(Util.toColumnName(attributeName));
115             String columnName = optimalColumnName;
116             if (map.inverse().get(columnName) != null || isReservedWord(columnName)) {
117                 int i = 1;
118                 while (map.inverse().get(columnName + "_" + i) != null) {
119                     i++;
120                 }
121                 columnName = columnName + "_" + i;
122             }
123             map.put(key, columnName);
124             return columnName;
125         }
126     }
127 
128     private static String getKey(String cls, String attributeName) {
129         return cls + "_._" + attributeName;
130     }
131 
132     private static String getKey(String viewedClass, BigInteger rnum) {
133         return viewedClass + "_._R" + rnum;
134     }
135 
136     public String toTableName(String schema, String className) {
137         if (referencedTables.get(schema) == null) {
138             BiMap<String, String> bimap = HashBiMap.create();
139             referencedTables.put(schema, bimap);
140         }
141         BiMap<String, String> map = referencedTables.get(schema);
142         String key = getKey(schema, className);
143         if (map.get(key) != null)
144             return map.get(key);
145         else {
146             String optimalName = Util.lowerFirst(Util.toColumnName(className));
147             String name = optimalName;
148             if (map.inverse().get(name) != null || isReservedWord(name)) {
149                 int i = 1;
150                 while (map.inverse().get(name + "_" + i) != null) {
151                     i++;
152                 }
153                 name = name + "_" + i;
154             }
155             map.put(key, name);
156             return name;
157         }
158     }
159 
160     private boolean isReservedWord(String name) {
161         return reservedWords.contains(name.toUpperCase());
162     }
163 }