001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.tools.generators;
010:
011: import com.completex.objective.components.persistency.MetaColumn;
012:
013: import java.io.PrintStream;
014: import java.util.Arrays;
015: import java.util.StringTokenizer;
016:
017: /**
018: * @author Gennady Krizhevsky
019: */
020: public class NameHelper {
021:
022: static PrefixResover prefixResover = new PrefixResover();
023: static SuffixResover suffixResover = new SuffixResover();
024:
025: public static final int AS_IS = 0;
026: public static final int LOWER = 1;
027: public static final int UPPER = 2;
028: public static final String EXACT_NAME_LEFT_BRACKET = "(";
029: public static final String EXACT_NAME_RIGHT_BRACKET = ")";
030: public static final String NEGATE = "!";
031: public static final char CHAR_BEGIN = '(';
032: public static final char CHAR_END = ')';
033: public static final String SEP_PATTERN = "\\|";
034:
035: public String parseColumnAlias(MetaColumn metaColumn) {
036: String alias = metaColumn.getColumnAlias();
037: return NameHelper.isExactAlias(alias) ? NameHelper
038: .parseExactAlias(alias) : alias;
039: }
040:
041: public static String parseExactAlias(String token) {
042: if (isExactAlias(token)) {
043: if (token.endsWith(EXACT_NAME_RIGHT_BRACKET)) {
044: return token.substring(1, token.length() - 1);
045: } else {
046: throw new IllegalArgumentException(
047: "Cannot parse alias : " + token);
048: }
049: } else {
050: return token;
051: }
052: }
053:
054: public static boolean isExactAlias(String token) {
055: return token.startsWith(EXACT_NAME_LEFT_BRACKET);
056: }
057:
058: public static String name(String prefix, String name, String sep,
059: int letterCase) {
060: String rc;
061: if (!isMixedCase(name)) {
062: rc = ((prefix == null ? "" : prefix) + name).toUpperCase();
063: } else {
064: StringBuffer buffer = new StringBuffer();
065: for (int i = 0; i < name.length(); i++) {
066: char ch = name.charAt(i);
067: if (Character.isUpperCase(ch) && i > 0) {
068: buffer.append(sep);
069: }
070: buffer.append(ch);
071: }
072: rc = (prefix == null ? "" : prefix) + buffer.toString();
073: if (letterCase == UPPER) {
074: rc = rc.toUpperCase();
075: } else if (letterCase == LOWER) {
076: rc = rc.toLowerCase();
077: }
078: }
079: return rc.replaceAll("#", "");
080: }
081:
082: public static String javaConstName(String prefix, String name) {
083: if (isExactAlias(name)) {
084: name = parseExactAlias(name);
085: }
086: String rc;
087: if (!isMixedCase(name)) {
088: rc = ((prefix == null ? "" : prefix) + name).toUpperCase();
089: } else {
090: //
091: // Mixed case:
092: //
093: StringBuffer assembly = new StringBuffer();
094: String[] parts = name.split("_+");
095: for (int i = 0; i < parts.length; i++) {
096: String part = parts[i];
097: part = partForMixedCase(part);
098: assembly.append(part);
099: if (i < parts.length - 1) {
100: assembly.append("_");
101: }
102: }
103: name = assembly.toString();
104: rc = ((prefix == null ? "" : prefix) + name).toUpperCase();
105: }
106: return rc.replaceAll("#", "");
107: }
108:
109: private static String partForMixedCase(String name) {
110: name = replaceUnderScoreForMixed(name);
111:
112: StringBuffer buffer = new StringBuffer();
113: StringBuffer partBuffer = new StringBuffer();
114: MonoBuffer monoBuffer = new MonoBuffer();
115: for (int i = 0; i < name.length(); i++) {
116: char ch = name.charAt(i);
117: partBuffer.append(ch);
118: monoBuffer.append(ch);
119: buffer.append(ch);
120: if (monoBuffer.isCaseChanged()) {
121: int offset = buffer.length() - 1;
122: if (monoBuffer.bufferMinus1Size() > 1) {
123: insertUnderScore(buffer, offset);
124: } else if (monoBuffer.bufferMinus1Size() == 1
125: && monoBuffer.bufferMinus2Size() == 1
126: && monoBuffer.bufferSize() == 1) {
127: char chAt = (char) -1;
128: int prevUpderscore = offset - 2;
129: if (prevUpderscore > 0) {
130: chAt = buffer.charAt(prevUpderscore);
131: }
132: if (!"_".equals(String.valueOf(chAt))) {
133: buffer.insert(offset, "_");
134: }
135: }
136: }
137: }
138: return buffer.toString();
139: }
140:
141: public static String inverseCase(String name) {
142: StringBuffer buffer = new StringBuffer(name);
143: for (int i = 0; i < buffer.length(); i++) {
144: char ch = buffer.charAt(i);
145: buffer.setCharAt(i, inverseCase(ch, ch));
146: }
147: return buffer.toString();
148: }
149:
150: private static String replaceUnderScoreForMixed(String name) {
151: StringBuffer buffer = new StringBuffer(name);
152: int index = -1;
153: while ((index = buffer.indexOf("_", index + 1)) >= 0) {
154: int indexBefore = index - 1;
155: int indexAfter = index + 1;
156:
157: if (indexBefore >= 0) {
158: char charBefore = buffer.charAt(indexBefore);
159: char charAfter = buffer.charAt(indexAfter);
160: char ch = inverseCase(charBefore, charAfter);
161: buffer.setCharAt(indexAfter, ch);
162: }
163: }
164:
165: name = buffer.toString();
166: name = name.replaceAll("_", "");
167:
168: return name;
169: }
170:
171: private static char inverseCase(char charBefore, char charAfter) {
172: char ch = charAfter;
173: if (Character.isUpperCase(charBefore)) {
174: ch = Character.toLowerCase(charAfter);
175: } else if (Character.isLowerCase(ch)) {
176: ch = Character.toUpperCase(charAfter);
177: }
178: return ch;
179: }
180:
181: private static void insertUnderScore(StringBuffer buffer, int offset) {
182: buffer.insert(offset, "_");
183: }
184:
185: public static boolean isMixedCase(String name) {
186: boolean hasUpper = false;
187: boolean hasLower = false;
188: for (int i = 0; i < name.length(); i++) {
189: char ch = name.charAt(i);
190: if (Character.isUpperCase(ch)) {
191: hasUpper = true;
192: } else if (Character.isLowerCase(ch)) {
193: hasLower = true;
194: }
195: }
196: return hasLower && hasUpper;
197: }
198:
199: public static String propertyName(String name, String prefix,
200: String suffix) {
201: return javaName(name, prefix, suffix, false,
202: isMainPattern(name));
203: }
204:
205: public static String javaName(String name, String prefix,
206: String suffix, boolean calitalizeFirstChar) {
207: return javaName(name, prefix, suffix, calitalizeFirstChar,
208: isMainPattern(name));
209: }
210:
211: public static String javaName(String name, String prefix,
212: String suffix, boolean calitalizeFirstChar,
213: boolean mainPattern) {
214: prefix = prefix == null ? "" : prefix;
215: suffix = suffix == null ? "" : suffix;
216: if (isExactAlias(name)) {
217: name = parseExactAlias(name);
218: name = addPrefixAndSuffix(name, prefix, suffix);
219: } else {
220: name = javaName0(name, prefix, suffix, calitalizeFirstChar,
221: mainPattern);
222: }
223: return name;
224: }
225:
226: private static String javaName0(String name, String prefix,
227: String suffix, boolean calitalizeFirstChar,
228: boolean mainPattern) {
229: StringTokenizer tokenizer = new StringTokenizer(name, "_");
230: String outputName = prefix;
231: boolean isFirstToken = true;
232: while (tokenizer.hasMoreTokens()) {
233: String token = tokenizer.nextToken();
234: if (mainPattern) {
235: token = token.toLowerCase();
236: }
237: StringBuffer buffer = new StringBuffer(token);
238: if (!isFirstToken || calitalizeFirstChar) { // If not 1st or calitalizeFirstChar - capitalize 1st letter:
239: buffer.setCharAt(0, (Character.toString(buffer
240: .charAt(0)).toUpperCase()).charAt(0));
241: } else {
242: isFirstToken = false;
243: }
244: outputName += buffer.toString();
245: }
246: String rc = name.startsWith("_") ? "_" + outputName + suffix
247: : outputName + suffix;
248: return rc.replaceAll("#", "");
249: }
250:
251: public static String addPrefixAndSuffix(String name, String prefix,
252: String suffix) {
253: name = prefixResover.resolveFix(name, prefix);
254: name = suffixResover.resolveFix(name, suffix);
255: return name;
256: }
257:
258: public static String lowerFirstChar(String name) {
259: StringBuffer buffer = new StringBuffer(name);
260: buffer.setCharAt(0, (Character.toString(buffer.charAt(0))
261: .toLowerCase()).charAt(0));
262: return buffer.toString();
263: }
264:
265: public static String capitalizeFirstChar(String name) {
266: StringBuffer buffer = new StringBuffer(name);
267: buffer.setCharAt(0, (Character.toString(buffer.charAt(0))
268: .toUpperCase()).charAt(0));
269: return buffer.toString();
270: }
271:
272: public static boolean isMainPattern(String name) {
273: return !NameHelper.isMixedCase(name) || name.indexOf("_") >= 0;
274: }
275:
276: public static void println(String data, int level) {
277: System.out.println(indent(data, level));
278: }
279:
280: public static void println(String data, int level,
281: PrintStream printStream) {
282: if (printStream != null) {
283: printStream.println(NameHelper.indent(data, level));
284: printStream.flush();
285: }
286: }
287:
288: public static String indent(String data, int level) {
289: return spaces(level) + data;
290: }
291:
292: public static String spaces(int level) {
293: level = level < 0 ? 0 : level;
294: char[] spaces = new char[level * STEP];
295: Arrays.fill(spaces, ' ');
296: return new String(spaces);
297: }
298:
299: public static final int STEP = 4;
300:
301: /**
302: * Capitalizes field name in Java Bean style
303: *
304: * @param s
305: * @return field name in Java Bean capitalized style
306: */
307: public static String capitalizeField(String s) {
308: if (s == null || s.length() == 0) {
309: return s;
310: }
311: char chars[] = s.toCharArray();
312: chars[0] = Character.toUpperCase(chars[0]);
313: return new String(chars);
314: }
315:
316: /**
317: * Utility method to take a string and convert it to normal Java variable
318: * name capitalization. This normally means converting the first
319: * character from upper case to lower case, but in the (unusual) special
320: * case when there is more than one character and both the first and
321: * second characters are upper case, we leave it alone.
322: * <p>
323: * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
324: * as "URL".
325: *
326: * @param name The string to be decapitalized.
327: * @return The decapitalized version of the string.
328: */
329: public static String decapitalizeField(String name) {
330: if (name == null || name.length() == 0) {
331: return name;
332: }
333: if (name.length() > 1 && Character.isUpperCase(name.charAt(1))
334: && Character.isUpperCase(name.charAt(0))) {
335: return name;
336: }
337: char chars[] = name.toCharArray();
338: chars[0] = Character.toLowerCase(chars[0]);
339: return new String(chars);
340: }
341:
342: public static void main(String[] args) {
343: String name = "SctctcXzcxvzx";
344:
345: System.out.println(name("", name, "-", LOWER));
346:
347: name = "(aaaBBBccc)";
348: System.out.println(isExactAlias(name));
349: System.out.println(parseExactAlias(name));
350: }
351:
352: public static class PrefixResover extends FixResolver {
353: protected String removeFix(String name, String fix) {
354: if (name.startsWith(fix)) {
355: name = name.substring(fix.length());
356: }
357: return name;
358: }
359:
360: protected String addFix(String name, String fix) {
361: name = fix + name;
362: return name;
363: }
364:
365: }
366:
367: public static class SuffixResover extends FixResolver {
368: protected String removeFix(String name, String fix) {
369: if (name.endsWith(fix)) {
370: name = name.substring(0, name.length() - fix.length());
371: }
372: return name;
373: }
374:
375: protected String addFix(String name, String fix) {
376: name = name + fix;
377: return name;
378: }
379:
380: }
381:
382: public static abstract class FixResolver {
383: public String resolveFix(String name, String fix) {
384: if (fix != null) {
385: if (fix.startsWith(NEGATE)) {
386: if (fix.length() == 1) {
387: throw new IllegalArgumentException(
388: "Prefix/suffix consists of " + NEGATE
389: + " only");
390: }
391: if (fix.charAt(1) == CHAR_BEGIN) {
392: int endNegatePos = fix.indexOf(CHAR_END);
393: if (endNegatePos < 0) {
394: throw new IllegalArgumentException(
395: "Found '"
396: + CHAR_BEGIN
397: + "' beginning of prefix/suffix pattern w/o end '"
398: + CHAR_END + "': " + fix);
399: } else if (endNegatePos <= 2) {
400: throw new IllegalArgumentException(
401: "Found end '"
402: + CHAR_END
403: + "' of prefix/suffix pattern in wrong position ': "
404: + fix);
405: }
406:
407: String inFix = fix.substring(2, endNegatePos);
408: String[] tokens = inFix.split(SEP_PATTERN);
409: for (int i = 0; i < tokens.length; i++) {
410: String token = tokens[i];
411: String modName = removeFix(name, token);
412: if (!name.equals(modName)) {
413: name = modName;
414: break;
415: }
416: }
417: int realEndPos = fix.length() - 1;
418: if (endNegatePos != realEndPos) {
419: String restFix = fix
420: .substring(endNegatePos + 1);
421: // System.err.println("endNegatePos " + endNegatePos + " != realEndPos " + realEndPos
422: // + "; restFix = " + restFix);
423:
424: name = resolveFix(name, restFix);
425: }
426: } else {
427: String inFix = fix.substring(1);
428: name = removeFix(name, inFix);
429: }
430: } else {
431: int beginNegatePos = fix.indexOf(NEGATE);
432: if (beginNegatePos >= 0) {
433: String beginFix = fix.substring(0,
434: beginNegatePos);
435: name = addFix(name, beginFix);
436: String restFix = fix.substring(beginNegatePos);
437: name = resolveFix(name, restFix);
438: } else {
439: name = addFix(name, fix);
440: }
441: }
442: }
443:
444: return name;
445: }
446:
447: protected abstract String addFix(String name, String fix);
448:
449: protected abstract String removeFix(String name, String fix);
450: }
451: }
|