blob: 9cfb2406f18b33143d8b253a3656ad41182f211a [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2005, 2006, 2007 Springsite BV (The Netherlands) and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Martin Taal - Initial API and implementation
*
* </copyright>
*
* $Id: TeneoSQLNameStrategy.java,v 1.2 2007/07/18 18:57:16 mtaal Exp $
*/
package org.eclipse.emf.teneo.mapping.strategy.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Differences between this implementation and the ClassicSQLNameStrategy is the way truncation is
* done if a name is longer than the sql name length constraint. To truncate a name this class will
* first remove vowels (in the order: u, o, a, e, i) and if that is not enough it will truncate the
* different parts of a name (separated by _).
*
* @author <a href="mtaal@elver.org">Martin Taal</a>
* @version $Revision: 1.2 $
*/
public class TeneoSQLNameStrategy extends ClassicSQLNameStrategy {
// The logger
protected static final Log log = LogFactory.getLog(TeneoSQLNameStrategy.class);
private static String[] removables = new String[] { "u", "o", "a", "e", "i" };
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.teneo.mapping.strategy.impl.ClassicSQLNameStrategy#trunc(int,
* java.lang.String, boolean)
*/
@Override
public String trunc(int maxSqlLength, String truncName, boolean truncPrefix) {
String correctedName = truncName.replace('.', '_');
if (maxSqlLength == -1) {
return correctedName;
}
if (correctedName.length() <= maxSqlLength) {
return correctedName;
}
// first do some standard things
// truncate the standard e_id
correctedName = correctedName.replaceAll("e_id", "id");
if (correctedName.length() <= maxSqlLength) {
return correctedName;
}
// now do vowel truncation
for (String vowel : getRemovableCharacters()) {
while (correctedName.indexOf(vowel) != -1 || correctedName.indexOf(vowel.toUpperCase()) != -1) {
if (correctedName.indexOf(vowel) != -1) {
correctedName = correctedName.replaceFirst(vowel, "");
} else {
correctedName = correctedName.replaceFirst(vowel.toUpperCase(), "");
}
correctedName = correctedName.replaceAll("__", "_");
if (correctedName.startsWith("_")) {
correctedName = correctedName.substring(1);
}
if (correctedName.length() <= maxSqlLength) {
return correctedName;
}
}
}
// still failed do length truncation
return doLengthTruncation(maxSqlLength, correctedName);
}
private String doLengthTruncation(int maxSqlLength, String correctedName) {
// failed do length truncation with the remainder
final int underscore = correctedName.lastIndexOf('_');
if (underscore == -1) {
return correctedName.substring(0, maxSqlLength);
}
// now do the complex logic to truncate different parts
final String[] parts = correctedName.split("_");
int maxLength = -1;
for (String part : parts) {
if (part.length() > maxLength && part.length() > 0) {
maxLength = part.length();
}
}
// can this ever happen
int totalLength = correctedName.length();
while (maxLength > 1 && totalLength > maxSqlLength) {
totalLength = 0;
int newMax = 0;
for (int i = 0; i < parts.length; i++) {
if (parts[i].length() == maxLength) {
parts[i] = parts[i].substring(0, maxLength - 1);
}
if (parts[i].length() > newMax) {
newMax = parts[i].length();
}
totalLength += parts[i].length();
}
totalLength += parts.length - 1; // count the underscores
maxLength = newMax;
}
final StringBuffer result = new StringBuffer();
for (String part : parts) {
if (result.length() > 0) {
result.append("_");
}
result.append(part);
}
return result.toString();
}
/**
* Return the characters to remove, the character removal is done in order of the returned
* array. This method is provided to be overridden to pass a custom set of removable characters.
*/
protected String[] getRemovableCharacters() {
return removables;
}
}