001: package org.andromda.metafacades.uml;
002:
003: import java.text.CharacterIterator;
004: import java.text.StringCharacterIterator;
005:
006: import java.util.ArrayList;
007: import java.util.Collection;
008:
009: import org.andromda.core.common.ExceptionUtils;
010: import org.apache.commons.lang.StringEscapeUtils;
011: import org.apache.commons.lang.StringUtils;
012:
013: /**
014: * Utilities for dealing with entity metafacades
015: *
016: * @author Chad Brandon
017: */
018: public class EntityMetafacadeUtils {
019: /**
020: * <p/> Converts a string following the Java naming conventions to a
021: * database attribute name. For example convert customerName to
022: * CUSTOMER_NAME.
023: * </p>
024: *
025: * @param modelElementName the string to convert
026: * @param separator character used to separate words
027: * @return string converted to database attribute format
028: */
029: public static String toSqlName(String modelElementName,
030: Object separator) {
031: ExceptionUtils.checkEmpty("modelElementName", modelElementName);
032:
033: StringBuffer sqlName = new StringBuffer();
034: StringCharacterIterator iterator = new StringCharacterIterator(
035: StringUtils.uncapitalize(modelElementName));
036:
037: for (char character = iterator.first(); character != CharacterIterator.DONE; character = iterator
038: .next()) {
039: if (Character.isUpperCase(character)) {
040: sqlName.append(separator);
041: }
042: character = Character.toUpperCase(character);
043: sqlName.append(character);
044: }
045: return StringEscapeUtils.escapeSql(sqlName.toString());
046: }
047:
048: /**
049: * Gets the SQL name. (i.e. column name, table name, etc.). If it can't find
050: * the corresponding tagged value with the specified <code>name</code>,
051: * then it uses the element name by default and just returns that.
052: *
053: * @param prefix the optional prefix to add to the sql name (i.e. table name
054: * prefix, etc.).
055: * @param element from which to retrieve the SQL name.
056: * @param name the name of the tagged value.
057: * @param nameMaxLength if this is not null, then the name returned will be
058: * trimmed to this length (if it happens to be longer).
059: * @param separator character used to separate words
060: * @return the SQL name as a String.
061: */
062: public static String getSqlNameFromTaggedValue(String prefix,
063: ModelElementFacade element, String name,
064: Short nameMaxLength, Object separator) {
065: return getSqlNameFromTaggedValue(prefix, element, name,
066: nameMaxLength, null, separator);
067: }
068:
069: /**
070: * Gets the SQL name. (i.e. column name, table name, etc.). If it can't find
071: * the corresponding tagged value with the specified <code>name</code>,
072: * then it uses the element name by default and just returns that.
073: *
074: * @param element from which to retrieve the SQL name.
075: * @param name the name of the tagged value.
076: * @param nameMaxLength if this is not null, then the name returned will be
077: * trimmed to this length (if it happens to be longer).
078: * @param suffix the optional suffix to add to the sql name (i.e. foreign
079: * key suffix, etc.)
080: * @param separator character used to separate words
081: * @return the SQL name as a String.
082: */
083: public static String getSqlNameFromTaggedValue(
084: ModelElementFacade element, String name,
085: Short nameMaxLength, String suffix, Object separator) {
086: return getSqlNameFromTaggedValue(null, element, name,
087: nameMaxLength, suffix, separator);
088: }
089:
090: /**
091: * Gets the SQL name. (i.e. column name, table name, etc.). If it can't find
092: * the corresponding tagged value with the specified <code>name</code>,
093: * then it uses the element name by default and just returns that.
094: *
095: * @param element from which to retrieve the SQL name.
096: * @param name the name of the tagged value.
097: * @param nameMaxLength if this is not null, then the name returned will be
098: * trimmed to this length (if it happens to be longer).
099: * @param separator character used to separate words
100: * @return the SQL name as a String.
101: */
102: public static String getSqlNameFromTaggedValue(
103: ModelElementFacade element, String name,
104: Short nameMaxLength, Object separator) {
105: return getSqlNameFromTaggedValue(null, element, name,
106: nameMaxLength, null, separator);
107: }
108:
109: /**
110: * Gets the SQL name. (i.e. column name, table name, etc.). If it can't find
111: * the corresponding tagged value with the specified <code>name</code>,
112: * then it uses the element name by default and just returns that.
113: *
114: * @param prefix the optional prefix to add to the sql name (i.e. table name
115: * prefix, etc.).
116: * @param element from which to retrieve the SQL name.
117: * @param name the name of the tagged value.
118: * @param nameMaxLength if this is not null, then the name returned will be
119: * trimmed to this length (if it happens to be longer).
120: * @param suffix the optional suffix to add to the sql name (i.e. foreign
121: * key suffix, etc.)
122: * @param separator character used to separate words
123: * @return the SQL name as a String.
124: */
125: public static String getSqlNameFromTaggedValue(String prefix,
126: final ModelElementFacade element, String name,
127: final Short nameMaxLength, String suffix,
128: final Object separator) {
129: if (element != null) {
130: Object value = element.findTaggedValue(name);
131: StringBuffer buffer = new StringBuffer(StringUtils
132: .trimToEmpty((String) value));
133: if (StringUtils.isEmpty(buffer.toString())) {
134: // if we can't find the tagValue then use the
135: // element name for the name
136: buffer = new StringBuffer(toSqlName(element.getName(),
137: separator));
138: suffix = StringUtils.trimToEmpty(suffix);
139: prefix = StringUtils.trimToEmpty(prefix);
140: if (nameMaxLength != null) {
141: final short maxLength = (short) (nameMaxLength
142: .shortValue()
143: - suffix.length() - prefix.length());
144: buffer = new StringBuffer(EntityMetafacadeUtils
145: .ensureMaximumNameLength(buffer.toString(),
146: new Short(maxLength)));
147: }
148: if (StringUtils.isNotBlank(prefix)) {
149: buffer.insert(0, prefix);
150: }
151: if (StringUtils.isNotBlank(suffix)) {
152: buffer.append(suffix);
153: }
154: }
155: name = buffer.toString();
156: }
157: return name;
158: }
159:
160: /**
161: * <p/> Trims the passed in value to the maximum name length.
162: * </p>
163: * If no maximum length has been set then this method does nothing.
164: *
165: * @param name the name length to check and trim if necessary
166: * @param nameMaxLength if this is not null, then the name returned will be
167: * trimmed to this length (if it happens to be longer).
168: * @return String the string to be used as SQL type
169: */
170: public static String ensureMaximumNameLength(String name,
171: Short nameMaxLength) {
172: if (StringUtils.isNotEmpty(name) && nameMaxLength != null) {
173: short max = nameMaxLength.shortValue();
174: if (name.length() > max) {
175: name = name.substring(0, max);
176: }
177: }
178: return name;
179: }
180:
181: /**
182: * Gets all identifiers for an entity. If 'follow' is true, and if
183: * no identifiers can be found on the entity, a search up the
184: * inheritance chain will be performed, and the identifiers from
185: * the first super class having them will be used. If no
186: * identifiers exist, a default identifier will be created if the
187: * allowDefaultIdentifiers property is set to true.
188: *
189: * @param entity the entity for which to retrieve the identifiers
190: * @param follow a flag indicating whether or not the inheritance hiearchy
191: * should be followed
192: * @return the collection of identifiers.
193: */
194: public static Collection getIdentifiers(final Entity entity,
195: final boolean follow) {
196: final Collection identifiers = new ArrayList(entity
197: .getAttributes());
198: MetafacadeUtils.filterByStereotype(identifiers,
199: UMLProfile.STEREOTYPE_IDENTIFIER);
200:
201: return identifiers.isEmpty() && follow
202: && entity.getGeneralization() instanceof Entity ? getIdentifiers(
203: (Entity) entity.getGeneralization(), follow)
204: : identifiers;
205: }
206:
207: /**
208: * Constructs a sql type name from the given <code>mappedName</code> and
209: * <code>columnLength</code>.
210: *
211: * @param typeName the actual type name (usually retrieved from a mappings
212: * file, ie NUMBER(19).
213: * @param columnLength the length of the column.
214: * @return the new name co
215: */
216: public static String constructSqlTypeName(final String typeName,
217: final String columnLength) {
218: String value = typeName;
219: if (StringUtils.isNotEmpty(typeName)) {
220: final char beginChar = '(';
221: final char endChar = ')';
222: final int beginIndex = value.indexOf(beginChar);
223: final int endIndex = value.indexOf(endChar);
224: if (beginIndex != -1 && endIndex != -1
225: && endIndex > beginIndex) {
226: String replacement = value.substring(beginIndex,
227: endIndex)
228: + endChar;
229: value = StringUtils.replace(value, replacement,
230: beginChar + columnLength + endChar);
231: } else {
232: value = value + beginChar + columnLength + endChar;
233: }
234: }
235: return value;
236: }
237: }
|