package org.jboss.ejb.plugins.cmp.jdbc.metadata;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Collection;
import org.jboss.deployment.DeploymentException;
import org.jboss.metadata.MetaData;
import org.w3c.dom.Element;
public final class JDBCTypeMappingMetaData
{
private static final String[] PRIMITIVES = {
"boolean", "byte", "char", "short", "int", "long", "float", "double"
};
private static final String[] PRIMITIVE_CLASSES = {
"java.lang.Boolean", "java.lang.Byte", "java.lang.Character",
"java.lang.Short", "java.lang.Integer", "java.lang.Long",
"java.lang.Float", "java.lang.Double"
};
public static final String CONCAT = "concat";
public static final String SUBSTRING = "substring";
public static final String LCASE = "lcase";
public static final String UCASE = "ucase";
public static final String LENGTH = "length";
public static final String LOCATE = "locate";
public static final String ABS = "abs";
public static final String SQRT = "sqrt";
public static final String COUNT = "count";
public static JDBCFunctionMappingMetaData COUNT_FUNC;
public static JDBCFunctionMappingMetaData MAX_FUNC;
public static JDBCFunctionMappingMetaData MIN_FUNC;
public static JDBCFunctionMappingMetaData AVG_FUNC;
public static JDBCFunctionMappingMetaData SUM_FUNC;
public static JDBCFunctionMappingMetaData MOD_FUNC;
static
{
try
{
COUNT_FUNC = new JDBCFunctionMappingMetaData("count", "count(?1 ?2)");
MAX_FUNC = new JDBCFunctionMappingMetaData("max", "max(?1 ?2)");
MIN_FUNC = new JDBCFunctionMappingMetaData("min", "min(?1 ?2)");
AVG_FUNC = new JDBCFunctionMappingMetaData("avg", "avg(?1 ?2)");
SUM_FUNC = new JDBCFunctionMappingMetaData("sum", "sum(?1 ?2)");
MOD_FUNC = new JDBCFunctionMappingMetaData("mod", "mod(?1, ?2)");
}
catch(DeploymentException e)
{
throw new IllegalStateException(e.getMessage());
}
}
private final String name;
private final HashMap mappings = new HashMap();
private final HashMap functionMappings = new HashMap();
private final String aliasHeaderPrefix;
private final String aliasHeaderSuffix;
private final int aliasMaxLength;
private final boolean subquerySupported;
private final String trueMapping;
private final String falseMapping;
private JDBCFunctionMappingMetaData rowLocking = null;
private JDBCFunctionMappingMetaData fkConstraint = null;
private JDBCFunctionMappingMetaData pkConstraint = null;
private JDBCFunctionMappingMetaData autoIncrement = null;
private JDBCFunctionMappingMetaData addColumn = null;
private JDBCFunctionMappingMetaData dropColumn = null;
private JDBCFunctionMappingMetaData alterColumn = null;
public JDBCTypeMappingMetaData(Element element) throws DeploymentException
{
name = MetaData.getUniqueChildContent(element, "name");
String rowLockingSQL = MetaData.getUniqueChildContent(element, "row-locking-template");
if(rowLockingSQL != null && !rowLockingSQL.trim().equals(""))
{
rowLocking = new JDBCFunctionMappingMetaData("row-locking", rowLockingSQL);
}
String pkConstraintSQL = MetaData.getUniqueChildContent(element, "pk-constraint-template");
if(pkConstraintSQL != null && !pkConstraintSQL.trim().equals(""))
{
pkConstraint = new JDBCFunctionMappingMetaData("pk-constraint", pkConstraintSQL);
}
String fkConstraintSQL = MetaData.getUniqueChildContent(element, "fk-constraint-template");
if(fkConstraintSQL != null && !fkConstraintSQL.trim().equals(""))
{
fkConstraint = new JDBCFunctionMappingMetaData("fk-constraint", fkConstraintSQL);
}
String alterColumnSQL = MetaData.getOptionalChildContent(element, "add-column-template");
if(alterColumnSQL != null && !alterColumnSQL.trim().equals(""))
{
addColumn = new JDBCFunctionMappingMetaData("add-column-template", alterColumnSQL);
}
else
{
addColumn = new JDBCFunctionMappingMetaData("add-column-template", "ALTER TABLE ?1 ADD ?2 ?3");
}
alterColumnSQL = MetaData.getOptionalChildContent(element, "alter-column-template");
if(alterColumnSQL != null && !alterColumnSQL.trim().equals(""))
{
alterColumn = new JDBCFunctionMappingMetaData("alter-column-template", alterColumnSQL);
}
else
{
alterColumn = new JDBCFunctionMappingMetaData("alter-column-template", "ALTER TABLE ?1 ALTER ?2 TYPE ?3");
}
alterColumnSQL = MetaData.getOptionalChildContent(element, "drop-column-template");
if(alterColumnSQL != null && !alterColumnSQL.trim().equals(""))
{
dropColumn = new JDBCFunctionMappingMetaData("drop-column-template", alterColumnSQL);
}
else
{
dropColumn = new JDBCFunctionMappingMetaData("drop-column-template", "ALTER TABLE ?1 DROP ?2");
}
String autoIncrementSQL = MetaData.getOptionalChildContent(element, "auto-increment-template");
if(autoIncrementSQL != null && !autoIncrementSQL.trim().equals(""))
{
autoIncrement = new JDBCFunctionMappingMetaData("auto-increment", autoIncrementSQL);
}
Iterator iterator = MetaData.getChildrenByTagName(element, "mapping");
while(iterator.hasNext())
{
Element mappingElement = (Element)iterator.next();
JDBCMappingMetaData mapping = new JDBCMappingMetaData(mappingElement);
mappings.put(mapping.getJavaType(), mapping);
}
addDefaultFunctionMapping();
Iterator functions = MetaData.getChildrenByTagName(element, "function-mapping");
while(functions.hasNext())
{
Element mappingElement = (Element)functions.next();
JDBCFunctionMappingMetaData functionMapping = new JDBCFunctionMappingMetaData(mappingElement);
functionMappings.put(functionMapping.getFunctionName().toLowerCase(), functionMapping);
}
aliasHeaderPrefix = MetaData.getUniqueChildContent(element, "alias-header-prefix");
aliasHeaderSuffix = MetaData.getUniqueChildContent(element, "alias-header-suffix");
String aliasMaxLengthString = MetaData.getUniqueChildContent(element, "alias-max-length");
try
{
aliasMaxLength = Integer.parseInt(aliasMaxLengthString);
}
catch(NumberFormatException e)
{
throw new DeploymentException("Invalid number format in " +
"alias-max-length " + aliasMaxLengthString + "': " + e);
}
String subquerySupportedStr = MetaData.getUniqueChildContent(element, "subquery-supported");
subquerySupported = Boolean.valueOf(subquerySupportedStr).booleanValue();
trueMapping = MetaData.getUniqueChildContent(element, "true-mapping");
falseMapping = MetaData.getUniqueChildContent(element, "false-mapping");
}
public String getName()
{
return name;
}
public String getAliasHeaderPrefix()
{
return aliasHeaderPrefix;
}
public String getAliasHeaderSuffix()
{
return aliasHeaderSuffix;
}
public int getAliasMaxLength()
{
return aliasMaxLength;
}
public boolean isSubquerySupported()
{
return subquerySupported;
}
public String getTrueMapping()
{
return trueMapping;
}
public String getFalseMapping()
{
return falseMapping;
}
public JDBCMappingMetaData getTypeMappingMetaData(Class type)
{
String javaType = type.getName();
for(int i = 0; i < PRIMITIVES.length; i++)
{
if(javaType.equals(PRIMITIVES[i]))
{
javaType = PRIMITIVE_CLASSES[i];
break;
}
}
JDBCMappingMetaData mapping = (JDBCMappingMetaData)mappings.get(javaType);
if(mapping == null)
{
mapping = (JDBCMappingMetaData)mappings.get("java.lang.Object");
}
return mapping;
}
public JDBCFunctionMappingMetaData getFunctionMapping(String name)
{
JDBCFunctionMappingMetaData funcMapping = (JDBCFunctionMappingMetaData)functionMappings.get(name.toLowerCase());
if(funcMapping == null)
throw new IllegalStateException("Function " + name + " is not defined for " + this.name);
return funcMapping;
}
public JDBCFunctionMappingMetaData getRowLockingTemplate()
{
return rowLocking;
}
public JDBCFunctionMappingMetaData getPkConstraintTemplate()
{
return pkConstraint;
}
public JDBCFunctionMappingMetaData getFkConstraintTemplate()
{
return fkConstraint;
}
public JDBCFunctionMappingMetaData getAutoIncrementTemplate()
{
return autoIncrement;
}
public JDBCFunctionMappingMetaData getAddColumnTemplate()
{
return addColumn;
}
public JDBCFunctionMappingMetaData getDropColumnTemplate()
{
return dropColumn;
}
public JDBCFunctionMappingMetaData getAlterColumnTemplate()
{
return alterColumn;
}
public Collection getMappings()
{
return mappings.values();
}
private void addDefaultFunctionMapping()
{
JDBCFunctionMappingMetaData function;
function = new JDBCFunctionMappingMetaData("concat",
new String[]{
"{fn concat(",
", ",
")}"
},
new int[]{0, 1});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("substring",
new String[]{
"{fn substring(",
", ",
", ",
")}"
},
new int[]{0, 1, 2});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("lcase",
new String[]{
"{fn lcase(",
")}"
},
new int[]{0});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("ucase",
new String[]{
"{fn ucase(",
")}"
},
new int[]{0});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("length",
new String[]{
"{fn length(",
")}"
},
new int[]{0});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("locate",
new String[]{
"{fn locate(",
", ",
", ",
")}"
},
new int[]{0, 1, 2});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("abs",
new String[]{
"{fn abs(",
")}"
},
new int[]{0});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
function = new JDBCFunctionMappingMetaData("sqrt",
new String[]{
"{fn sqrt(",
")}"
},
new int[]{0});
functionMappings.put(function.getFunctionName().toLowerCase(), function);
}
}