001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.entity.model;
019:
020: import java.io.*;
021:
022: import org.ofbiz.base.util.*;
023:
024: /**
025: * Generic Entity - General Utilities
026: *
027: */
028: public class ModelUtil {
029:
030: public static final String module = ModelUtil.class.getName();
031:
032: /**
033: * Changes the first letter of the passed String to upper case.
034: * @param string The passed String
035: * @return A String with an upper case first letter
036: */
037: public static String upperFirstChar(String string) {
038: if (string == null)
039: return null;
040: if (string.length() <= 1)
041: return string.toLowerCase();
042: StringBuffer sb = new StringBuffer(string);
043:
044: sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
045: return sb.toString();
046: }
047:
048: /**
049: * Changes the first letter of the passed String to lower case.
050: *
051: * @param string The passed String
052: * @return A String with a lower case first letter
053: */
054: public static String lowerFirstChar(String string) {
055: if (string == null)
056: return null;
057: if (string.length() <= 1)
058: return string.toLowerCase();
059: StringBuffer sb = new StringBuffer(string);
060:
061: sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
062: return sb.toString();
063: }
064:
065: /** Converts a database name to a Java class name.
066: * The naming conventions used to allow for this are as follows: a database name (table or
067: * column) is in all capital letters, and the words are separated by an underscore
068: * (for example: NEAT_ENTITY_NAME or RANDOM_FIELD_NAME); a Java name (ejb or field) is in all
069: * lower case letters, except the letter at the beginning of each word (for example:
070: * NeatEntityName or RandomFieldName). The convention of using a capital letter at
071: * the beginning of a class name in Java, or a lower-case letter for the beginning of a
072: * variable name in Java is also used along with the Java name convention above.
073: * @param columnName The database name
074: * @return The Java class name
075: */
076: public static String dbNameToClassName(String columnName) {
077: return upperFirstChar(dbNameToVarName(columnName));
078: }
079:
080: /** Converts a database name to a Java variable name.
081: * The naming conventions used to allow for this are as follows: a database name (table or
082: * column) is in all capital letters, and the words are separated by an underscore
083: * (for example: NEAT_ENTITY_NAME or RANDOM_FIELD_NAME); a Java name (ejb or field) is in all
084: * lower case letters, except the letter at the beginning of each word (for example:
085: * NeatEntityName or RandomFieldName). The convention of using a capital letter at
086: * the beginning of a class name in Java, or a lower-case letter for the beginning of a
087: * variable name in Java is also used along with the Java name convention above.
088: * @param columnName The database name
089: * @return The Java variable name
090: */
091: public static String dbNameToVarName(String columnName) {
092: if (columnName == null)
093: return null;
094:
095: StringBuffer fieldName = new StringBuffer(columnName.length());
096:
097: boolean toUpper = false;
098: for (int i = 0; i < columnName.length(); i++) {
099: char ch = columnName.charAt(i);
100: if (ch == '_') {
101: toUpper = true;
102: } else if (toUpper) {
103: fieldName.append(Character.toUpperCase(ch));
104: toUpper = false;
105: } else {
106: fieldName.append(Character.toLowerCase(ch));
107: }
108: }
109:
110: return fieldName.toString();
111: }
112:
113: /**
114: * Converts a Java variable name to a database name.
115: * The naming conventions used to allow for this are as follows: a database name (table or
116: * column) is in all capital letters, and the words are separated by an underscore
117: * (for example: NEAT_ENTITY_NAME or RANDOM_FIELD_NAME); a Java name (ejb or field) is in all
118: * lower case letters, except the letter at the beginning of each word (for example:
119: * NeatEntityName or RandomFieldName). The convention of using a capital letter at
120: * the beginning of a class name in Java, or a lower-case letter for the beginning of a
121: * variable name in Java is also used along with the Java name convention above.
122: * @param javaName The Java variable name
123: * @return The database name
124: */
125: public static String javaNameToDbName(String javaName) {
126: if (javaName == null)
127: return null;
128: if (javaName.length() <= 0)
129: return "";
130: StringBuffer dbName = new StringBuffer();
131:
132: dbName.append(Character.toUpperCase(javaName.charAt(0)));
133: int namePos = 1;
134:
135: while (namePos < javaName.length()) {
136: char curChar = javaName.charAt(namePos);
137:
138: if (Character.isUpperCase(curChar))
139: dbName.append('_');
140: dbName.append(Character.toUpperCase(curChar));
141: namePos++;
142: }
143:
144: return dbName.toString();
145: }
146:
147: public static String vowelBag = "aeiouyAEIOUY";
148:
149: /** Start by removing all vowels, then pull 1 letter at a time off the end of each _ separated segment, go until it is less than or equal to the desired length
150: *
151: * @param dbName
152: * @param desiredLength
153: * @return shortened String
154: */
155: public static String shortenDbName(String dbName, int desiredLength) {
156: StringBuffer dbBuf = new StringBuffer(dbName);
157: if (dbBuf.length() > desiredLength) {
158: // remove one vowel at a time, starting at beginning
159: for (int i = dbBuf.length() - 1; i > 0; i--) {
160: // don't remove vowels that are at the beginning of the string (taken care of by the i > 0) or right after an underscore
161: if (dbBuf.charAt(i - 1) == '_') {
162: continue;
163: }
164:
165: char curChar = dbBuf.charAt(i);
166: if (vowelBag.indexOf(curChar) > 0) {
167: dbBuf.deleteCharAt(i);
168: }
169: }
170: }
171:
172: // remove all double underscores
173: while (dbBuf.indexOf("__") > 0) {
174: dbBuf.deleteCharAt(dbBuf.indexOf("__"));
175: }
176:
177: while (dbBuf.length() > desiredLength) {
178: boolean removedChars = false;
179:
180: int usIndex = dbBuf.lastIndexOf("_");
181: while (usIndex > 0 && dbBuf.length() > desiredLength) {
182: // if this is the first word in the group, don't pull letters off unless it is 4 letters or more
183: int prevUsIndex = dbBuf.lastIndexOf("_", usIndex - 1);
184: if (prevUsIndex < 0 && usIndex < 4) {
185: break;
186: }
187:
188: // don't remove characters to reduce the size two less than three characters between underscores
189: if (prevUsIndex >= 0 && (usIndex - prevUsIndex) <= 4) {
190: usIndex = prevUsIndex;
191: continue;
192: }
193:
194: // delete the second to last character instead of the last, better chance of being unique
195: dbBuf.deleteCharAt(usIndex - 2);
196: removedChars = true;
197: if (usIndex > 2) {
198: usIndex = dbBuf.lastIndexOf("_", usIndex - 2);
199: } else {
200: break;
201: }
202: }
203:
204: // now delete the char at the end of the string if necessary
205: if (dbBuf.length() > desiredLength) {
206: int removeIndex = dbBuf.length() - 1;
207: int prevRemoveIndex = dbBuf.lastIndexOf("_",
208: removeIndex - 1);
209: // don't remove characters to reduce the size two less than two characters between underscores
210: if (prevRemoveIndex < 0
211: || (removeIndex - prevRemoveIndex) >= 3) {
212: // delete the second to last character instead of the last, better chance of being unique
213: dbBuf.deleteCharAt(removeIndex - 1);
214: removedChars = true;
215: }
216: }
217:
218: // remove all double underscores
219: while (dbBuf.indexOf("__") > 0) {
220: dbBuf.deleteCharAt(dbBuf.indexOf("__"));
221: removedChars = true;
222: }
223:
224: // if we didn't remove anything break out to avoid an infinite loop
225: if (!removedChars) {
226: break;
227: }
228: }
229:
230: // remove all double underscores
231: while (dbBuf.indexOf("__") > 0) {
232: dbBuf.deleteCharAt(dbBuf.indexOf("__"));
233: }
234:
235: while (dbBuf.length() > desiredLength) {
236: // still not short enough, get more aggressive
237: // don't remove the first segment, just remove the second over and over until we are short enough
238: int firstUs = dbBuf.indexOf("_");
239: if (firstUs > 0) {
240: int nextUs = dbBuf.indexOf("_", firstUs + 1);
241: if (nextUs > 0) {
242: //Debug.logInfo("couldn't shorten enough normally, removing second segment from " + dbBuf, module);
243: dbBuf.delete(firstUs, nextUs);
244: }
245: }
246: }
247:
248: //Debug.logInfo("Shortened " + dbName + " to " + dbBuf.toString(), module);
249: return dbBuf.toString();
250: }
251:
252: /**
253: * Converts a package name to a path by replacing all '.' characters with the File.separatorChar character.
254: * Is therefore platform independent.
255: * @param packageName The package name.
256: * @return The path name corresponding to the specified package name.
257: */
258: public static String packageToPath(String packageName) {
259: // just replace all of the '.' characters with the folder separater character
260: return packageName.replace('.', File.separatorChar);
261: }
262:
263: /**
264: * Replaces all occurances of oldString in mainString with newString
265: * @param mainString The original string
266: * @param oldString The string to replace
267: * @param newString The string to insert in place of the old
268: * @return mainString with all occurances of oldString replaced by newString
269: */
270: public static String replaceString(String mainString,
271: String oldString, String newString) {
272: return StringUtil.replaceString(mainString, oldString,
273: newString);
274: }
275:
276: public static String induceFieldType(String sqlTypeName,
277: int length, int precision,
278: ModelFieldTypeReader fieldTypeReader) {
279: if (sqlTypeName == null)
280: return "invalid";
281:
282: if (sqlTypeName.equalsIgnoreCase("VARCHAR")
283: || sqlTypeName.equalsIgnoreCase("VARCHAR2")
284: || (sqlTypeName.equalsIgnoreCase("CHAR") && length > 1)) {
285: if (length <= 10)
286: return "very-short";
287: if (length <= 60)
288: return "short-varchar";
289: if (length <= 255)
290: return "long-varchar";
291: return "very-long";
292: } else if (sqlTypeName.equalsIgnoreCase("TEXT")) {
293: return "very-long";
294: } else if (sqlTypeName.equalsIgnoreCase("INT")
295: || sqlTypeName.equalsIgnoreCase("SMALLINT")
296: || sqlTypeName.equalsIgnoreCase("DECIMAL")
297: || sqlTypeName.equalsIgnoreCase("NUMERIC")) {
298: if (length > 18 || precision > 6)
299: return "invalid-" + sqlTypeName + ":" + length + ":"
300: + precision;
301: if (precision == 0)
302: return "numeric";
303: if (precision == 2)
304: return "currency-amount";
305: if (precision <= 6)
306: return "floating-point";
307: return "invalid-" + sqlTypeName + ":" + length + ":"
308: + precision;
309: } else if (sqlTypeName.equalsIgnoreCase("BLOB")
310: || sqlTypeName.equalsIgnoreCase("OID")) {
311: return "blob";
312: } else if (sqlTypeName.equalsIgnoreCase("DATETIME")
313: || sqlTypeName.equalsIgnoreCase("TIMESTAMP")) {
314: return "date-time";
315: } else if (sqlTypeName.equalsIgnoreCase("DATE")) {
316: return "date";
317: } else if (sqlTypeName.equalsIgnoreCase("TIME")) {
318: return "time";
319: } else if (sqlTypeName.equalsIgnoreCase("CHAR") && length == 1) {
320: return "indicator";
321: } else {
322: return "invalid-" + sqlTypeName + ":" + length + ":"
323: + precision;
324: }
325: }
326: }
|