View Javadoc
1   /**
2    *    Copyright 2006-2016 the original author or authors.
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 org.mybatis.generator.api;
17  
18  import static org.mybatis.generator.internal.util.EqualsUtil.areEqual;
19  import static org.mybatis.generator.internal.util.HashCodeUtil.SEED;
20  import static org.mybatis.generator.internal.util.HashCodeUtil.hash;
21  import static org.mybatis.generator.internal.util.JavaBeansUtil.getCamelCaseString;
22  import static org.mybatis.generator.internal.util.StringUtility.composeFullyQualifiedTableName;
23  import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
24  
25  import org.mybatis.generator.config.Context;
26  
27  /**
28   * The Class FullyQualifiedTable.
29   *
30   * @author Jeff Butler
31   */
32  public class FullyQualifiedTable {
33  
34      /** The introspected catalog. */
35      private String introspectedCatalog;
36  
37      /** The introspected schema. */
38      private String introspectedSchema;
39  
40      /** The introspected table name. */
41      private String introspectedTableName;
42  
43      /** The runtime catalog. */
44      private String runtimeCatalog;
45  
46      /** The runtime schema. */
47      private String runtimeSchema;
48  
49      /** The runtime table name. */
50      private String runtimeTableName;
51  
52      /** The domain object name. */
53      private String domainObjectName;
54      
55      /** The domain object sub package. */
56      private String domainObjectSubPackage;
57  
58      /** The alias. */
59      private String alias;
60  
61      /** The ignore qualifiers at runtime. */
62      private boolean ignoreQualifiersAtRuntime;
63  
64      /** The beginning delimiter. */
65      private String beginningDelimiter;
66  
67      /** The ending delimiter. */
68      private String endingDelimiter;
69  
70      /**
71       * This object is used to hold information related to the table itself, not the columns in the table.
72       *
73       * @param introspectedCatalog
74       *            the actual catalog of the table as returned from DatabaseMetaData. This value should only be set if
75       *            the user configured a catalog. Otherwise the DatabaseMetaData is reporting some database default that
76       *            we don't want in the generated code.
77       * @param introspectedSchema
78       *            the actual schema of the table as returned from DatabaseMetaData. This value should only be set if the
79       *            user configured a schema. Otherwise the DatabaseMetaData is reporting some database default that we
80       *            don't want in the generated code.
81       * @param introspectedTableName
82       *            the actual table name as returned from DatabaseMetaData
83       * @param domainObjectName
84       *            the configured domain object name for this table. If nothing is configured, we'll build the domain
85       *            object named based on the tableName or runtimeTableName.
86       * @param alias
87       *            a configured alias for the table. This alias will be added to the table name in the SQL
88       * @param ignoreQualifiersAtRuntime
89       *            if true, then the catalog and schema qualifiers will be ignored when composing fully qualified names
90       *            in the generated SQL. This is used, for example, when the user needs to specify a specific schema for
91       *            generating code but does not want the schema in the generated SQL
92       * @param runtimeCatalog
93       *            this is used to "rename" the catalog in the generated SQL. This is useful, for example, when
94       *            generating code against one catalog that should run with a different catalog.
95       * @param runtimeSchema
96       *            this is used to "rename" the schema in the generated SQL. This is useful, for example, when generating
97       *            code against one schema that should run with a different schema.
98       * @param runtimeTableName
99       *            this is used to "rename" the table in the generated SQL. This is useful, for example, when generating
100      *            code to run with an Oracle synonym. The user would have to specify the actual table name and schema
101      *            for generation, but would want to use the synonym name in the generated SQL
102      * @param delimitIdentifiers
103      *            if true, then the table identifiers will be delimited at runtime. The delimiter characters are
104      *            obtained from the Context.
105      * @param context
106      *            the context
107      */
108     public FullyQualifiedTable(String introspectedCatalog,
109             String introspectedSchema, String introspectedTableName,
110             String domainObjectName, String alias,
111             boolean ignoreQualifiersAtRuntime, String runtimeCatalog,
112             String runtimeSchema, String runtimeTableName,
113             boolean delimitIdentifiers, Context context) {
114         super();
115         this.introspectedCatalog = introspectedCatalog;
116         this.introspectedSchema = introspectedSchema;
117         this.introspectedTableName = introspectedTableName;
118         this.ignoreQualifiersAtRuntime = ignoreQualifiersAtRuntime;
119         this.runtimeCatalog = runtimeCatalog;
120         this.runtimeSchema = runtimeSchema;
121         this.runtimeTableName = runtimeTableName;
122         
123         if (stringHasValue(domainObjectName)) {
124             int index = domainObjectName.lastIndexOf('.');
125             if (index == -1) {
126                 this.domainObjectName = domainObjectName;
127             } else {
128                 this.domainObjectName = domainObjectName.substring(index + 1);
129                 this.domainObjectSubPackage = domainObjectName.substring(0, index);
130             }
131         }
132 
133         if (alias == null) {
134             this.alias = null;
135         } else {
136             this.alias = alias.trim();
137         }
138 
139         beginningDelimiter = delimitIdentifiers ? context
140                 .getBeginningDelimiter() : ""; //$NON-NLS-1$
141         endingDelimiter = delimitIdentifiers ? context.getEndingDelimiter()
142                 : ""; //$NON-NLS-1$
143     }
144 
145     /**
146      * Gets the introspected catalog.
147      *
148      * @return the introspected catalog
149      */
150     public String getIntrospectedCatalog() {
151         return introspectedCatalog;
152     }
153 
154     /**
155      * Gets the introspected schema.
156      *
157      * @return the introspected schema
158      */
159     public String getIntrospectedSchema() {
160         return introspectedSchema;
161     }
162 
163     /**
164      * Gets the introspected table name.
165      *
166      * @return the introspected table name
167      */
168     public String getIntrospectedTableName() {
169         return introspectedTableName;
170     }
171 
172     /**
173      * Gets the fully qualified table name at runtime.
174      *
175      * @return the fully qualified table name at runtime
176      */
177     public String getFullyQualifiedTableNameAtRuntime() {
178         StringBuilder localCatalog = new StringBuilder();
179         if (!ignoreQualifiersAtRuntime) {
180             if (stringHasValue(runtimeCatalog)) {
181                 localCatalog.append(runtimeCatalog);
182             } else if (stringHasValue(introspectedCatalog)) {
183                 localCatalog.append(introspectedCatalog);
184             }
185         }
186         if (localCatalog.length() > 0) {
187             addDelimiters(localCatalog);
188         }
189 
190         StringBuilder localSchema = new StringBuilder();
191         if (!ignoreQualifiersAtRuntime) {
192             if (stringHasValue(runtimeSchema)) {
193                 localSchema.append(runtimeSchema);
194             } else if (stringHasValue(introspectedSchema)) {
195                 localSchema.append(introspectedSchema);
196             }
197         }
198         if (localSchema.length() > 0) {
199             addDelimiters(localSchema);
200         }
201 
202         StringBuilder localTableName = new StringBuilder();
203         if (stringHasValue(runtimeTableName)) {
204             localTableName.append(runtimeTableName);
205         } else {
206             localTableName.append(introspectedTableName);
207         }
208         addDelimiters(localTableName);
209 
210         return composeFullyQualifiedTableName(localCatalog
211                 .toString(), localSchema.toString(), localTableName.toString(),
212                 '.');
213     }
214 
215     /**
216      * Gets the aliased fully qualified table name at runtime.
217      *
218      * @return the aliased fully qualified table name at runtime
219      */
220     public String getAliasedFullyQualifiedTableNameAtRuntime() {
221         StringBuilder sb = new StringBuilder();
222 
223         sb.append(getFullyQualifiedTableNameAtRuntime());
224 
225         if (stringHasValue(alias)) {
226             sb.append(' ');
227             sb.append(alias);
228         }
229 
230         return sb.toString();
231     }
232 
233     /**
234      * This method returns a string that is the fully qualified table name, with
235      * underscores as the separator.
236      * 
237      * @return the namespace
238      */
239     public String getIbatis2SqlMapNamespace() {
240         String localCatalog = stringHasValue(runtimeCatalog) ? runtimeCatalog
241                 : introspectedCatalog;
242         String localSchema = stringHasValue(runtimeSchema) ? runtimeSchema
243                 : introspectedSchema;
244         String localTable = stringHasValue(runtimeTableName) ? runtimeTableName
245                 : introspectedTableName;
246 
247         return composeFullyQualifiedTableName(
248                         ignoreQualifiersAtRuntime ? null : localCatalog,
249                         ignoreQualifiersAtRuntime ? null : localSchema,
250                         localTable, '_');
251     }
252 
253     /**
254      * Gets the domain object name.
255      *
256      * @return the domain object name
257      */
258     public String getDomainObjectName() {
259         if (stringHasValue(domainObjectName)) {
260             return domainObjectName;
261         } else if (stringHasValue(runtimeTableName)) {
262             return getCamelCaseString(runtimeTableName, true);
263         } else {
264             return getCamelCaseString(introspectedTableName, true);
265         }
266     }
267 
268     /* (non-Javadoc)
269      * @see java.lang.Object#equals(java.lang.Object)
270      */
271     @Override
272     public boolean equals(Object obj) {
273         if (this == obj) {
274             return true;
275         }
276 
277         if (!(obj instanceof FullyQualifiedTable)) {
278             return false;
279         }
280 
281         FullyQualifiedTable other = (FullyQualifiedTable) obj;
282 
283         return areEqual(this.introspectedTableName,
284                 other.introspectedTableName)
285                 && areEqual(this.introspectedCatalog,
286                         other.introspectedCatalog)
287                 && areEqual(this.introspectedSchema,
288                         other.introspectedSchema);
289     }
290 
291     /* (non-Javadoc)
292      * @see java.lang.Object#hashCode()
293      */
294     @Override
295     public int hashCode() {
296         int result = SEED;
297         result = hash(result, introspectedTableName);
298         result = hash(result, introspectedCatalog);
299         result = hash(result, introspectedSchema);
300 
301         return result;
302     }
303 
304     /* (non-Javadoc)
305      * @see java.lang.Object#toString()
306      */
307     @Override
308     public String toString() {
309         return composeFullyQualifiedTableName(
310                 introspectedCatalog, introspectedSchema, introspectedTableName,
311                 '.');
312     }
313 
314     /**
315      * Gets the alias.
316      *
317      * @return the alias
318      */
319     public String getAlias() {
320         return alias;
321     }
322 
323     /**
324      * Calculates a Java package fragment based on the table catalog and schema. If qualifiers are ignored, then this
325      * method will return an empty string
326      *
327      * @param isSubPackagesEnabled
328      *            the is sub packages enabled
329      * @return the subpackage for this table
330      */
331     public String getSubPackage(boolean isSubPackagesEnabled) {
332         StringBuilder sb = new StringBuilder();
333         if (!ignoreQualifiersAtRuntime && isSubPackagesEnabled) {
334             if (stringHasValue(runtimeCatalog)) {
335                 sb.append('.');
336                 sb.append(runtimeCatalog.toLowerCase());
337             } else if (stringHasValue(introspectedCatalog)) {
338                 sb.append('.');
339                 sb.append(introspectedCatalog.toLowerCase());
340             }
341 
342             if (stringHasValue(runtimeSchema)) {
343                 sb.append('.');
344                 sb.append(runtimeSchema.toLowerCase());
345             } else if (stringHasValue(introspectedSchema)) {
346                 sb.append('.');
347                 sb.append(introspectedSchema.toLowerCase());
348             }
349         }
350         
351         if (stringHasValue(domainObjectSubPackage)) {
352             sb.append('.');
353             sb.append(domainObjectSubPackage);
354         }
355 
356         // TODO - strip characters that are not valid in package names
357         return sb.toString();
358     }
359 
360     /**
361      * Adds the delimiters.
362      *
363      * @param sb
364      *            the sb
365      */
366     private void addDelimiters(StringBuilder sb) {
367         if (stringHasValue(beginningDelimiter)) {
368             sb.insert(0, beginningDelimiter);
369         }
370 
371         if (stringHasValue(endingDelimiter)) {
372             sb.append(endingDelimiter);
373         }
374     }
375 }