package org.jboss.xml.binding;
import org.jboss.util.Classes;
public final class Util
{
public static final char HYPHEN_MINUS = '\u002D';
public static final char FULL_STOP = '\u002E';
public static final char COLLON = '\u003A';
public static final char LOW_LINE = '\u005F';
public static final char MIDDLE_DOT = '\u00B7';
public static final char GREEK_ANO_TELEIA = '\u0387';
public static final char ARABIC_END_OF_AYAH = '\u06DD';
public static final char ARABIC_START_OF_RUB_EL_HIZB = '\u06DE';
public static String xmlNameToClassName(String name, boolean ignoreLowLine)
{
return XMLNameToJavaIdentifierConverter.PARSER.parse(XMLNameToJavaIdentifierConverter.CLASS_NAME,
name,
ignoreLowLine
);
}
public static String xmlNameToGetMethodName(String name, boolean ignoreLowLine)
{
return "get" + xmlNameToClassName(name, ignoreLowLine);
}
public static String xmlNameToSetMethodName(String name, boolean ignoreLowLine)
{
return "set" + xmlNameToClassName(name, ignoreLowLine);
}
public static String xmlNameToConstantName(String name)
{
return XMLNameToJavaIdentifierConverter.PARSER.parse(XMLNameToJavaIdentifierConverter.CONSTANT_NAME,
name,
true
);
}
public static String xmlNamespaceToJavaPackage(String namespace)
{
if(namespace.length() == 0)
{
return namespace;
}
char[] src = namespace.toLowerCase().toCharArray();
char[] dst = new char[namespace.length()];
int srcInd = 0;
while(src[srcInd++] != ':')
{
;
}
while(src[srcInd] == '/')
{
++srcInd;
}
if(src[srcInd] == 'w' && src[srcInd + 1] == 'w' && src[srcInd + 2] == 'w')
{
srcInd += 4;
}
int domainStart = srcInd;
while(srcInd < src.length && src[srcInd] != '/')
{
++srcInd;
}
int dstInd = 0;
for(int start = srcInd - 1, end = srcInd; true; --start)
{
if(start == domainStart)
{
System.arraycopy(src, start, dst, dstInd, end - start);
dstInd += end - start;
break;
}
if(src[start] == '.')
{
System.arraycopy(src, start + 1, dst, dstInd, end - start - 1);
dstInd += end - start;
dst[dstInd - 1] = '.';
end = start;
}
}
while(srcInd < src.length)
{
char c = src[srcInd++];
if(c == '/')
{
if(srcInd < src.length)
{
dst = append(dst, dstInd++, '.');
if(!Character.isJavaIdentifierStart(src[srcInd]))
{
dst = append(dst, dstInd++, '_');
}
}
}
else if(c == '.')
{
break;
}
else
{
dst = append(dst, dstInd++, Character.isJavaIdentifierPart(c) ? c : '_');
}
}
return String.valueOf(dst, 0, dstInd);
}
public static String xmlNameToClassName(String namespaceUri, String localName, boolean ignoreLowLine)
{
return namespaceUri == null || namespaceUri.length() == 0 ?
xmlNameToClassName(localName, ignoreLowLine) :
xmlNamespaceToJavaPackage(namespaceUri) + '.' + xmlNameToClassName(localName, ignoreLowLine);
}
public static boolean isAttributeType(final Class type)
{
return Classes.isPrimitive(type) ||
type == String.class ||
type == java.util.Date.class;
}
private static char[] append(char[] buf, int index, char ch)
{
if(index >= buf.length)
{
char[] tmp = buf;
buf = new char[index + 4];
System.arraycopy(tmp, 0, buf, 0, tmp.length);
}
buf[index] = ch;
return buf;
}
interface XMLNameToJavaIdentifierConverter
{
byte IGNORE = 0;
byte APPEND = 1;
byte APPEND_WITH_LOW_LINE = 2;
byte APPEND_UPPER_CASED = 3;
byte APPEND_UPPER_CASED_WITH_LOW_LINE = 4;
byte commandForNext(char prev, char next, boolean ignoreLowLine);
final class PARSER
{
static String parse(XMLNameToJavaIdentifierConverter converter, String xmlName, boolean ignoreLowLine)
{
if(xmlName == null || xmlName.length() == 0)
{
throw new IllegalArgumentException("Bad XML name: " + xmlName);
}
char c = xmlName.charAt(0);
int i = 1;
if(!Character.isJavaIdentifierStart(c) || (c == LOW_LINE && ignoreLowLine))
{
while(i < xmlName.length())
{
c = xmlName.charAt(i++);
if(Character.isJavaIdentifierStart(c) && !(c == LOW_LINE && ignoreLowLine))
{
break;
}
}
if(i == xmlName.length())
{
throw new IllegalArgumentException(
"XML name contains no valid character to start Java identifier: " + xmlName
);
}
}
char[] buf = new char[xmlName.length() - i + 1];
buf[0] = Character.toUpperCase(c);
int bufInd = 1;
while(i < xmlName.length())
{
char prev = c;
c = xmlName.charAt(i++);
byte command = converter.commandForNext(prev, c, ignoreLowLine);
switch(command)
{
case IGNORE:
break;
case APPEND:
buf = Util.append(buf, bufInd++, c);
break;
case APPEND_WITH_LOW_LINE:
buf = Util.append(buf, bufInd++, LOW_LINE);
buf = Util.append(buf, bufInd++, c);
break;
case APPEND_UPPER_CASED:
buf = Util.append(buf, bufInd++, Character.toUpperCase(c));
break;
case APPEND_UPPER_CASED_WITH_LOW_LINE:
buf = Util.append(buf, bufInd++, LOW_LINE);
buf = Util.append(buf, bufInd++, Character.toUpperCase(c));
break;
default:
throw new IllegalArgumentException("Unexpected command: " + command);
}
}
return new String(buf, 0, bufInd);
}
}
XMLNameToJavaIdentifierConverter CLASS_NAME = new XMLNameToJavaIdentifierConverter()
{
public byte commandForNext(char prev, char next, boolean ignoreLowLine)
{
byte command;
if(Character.isDigit(next))
{
command = APPEND;
}
else if(next == LOW_LINE)
{
command = ignoreLowLine ? IGNORE : APPEND;
}
else if(Character.isJavaIdentifierPart(next))
{
if(Character.isJavaIdentifierPart(prev) && !Character.isDigit(prev))
{
command = prev == LOW_LINE ? APPEND_UPPER_CASED : APPEND;
}
else
{
command = APPEND_UPPER_CASED;
}
}
else
{
command = IGNORE;
}
return command;
}
};
XMLNameToJavaIdentifierConverter CONSTANT_NAME = new XMLNameToJavaIdentifierConverter()
{
public byte commandForNext(char prev, char next, boolean ignoreLowLine)
{
byte command;
if(Character.isDigit(next))
{
command = Character.isDigit(prev) ? APPEND : APPEND_UPPER_CASED_WITH_LOW_LINE;
}
else if(Character.isJavaIdentifierPart(next))
{
if(Character.isDigit(prev))
{
command = APPEND_UPPER_CASED_WITH_LOW_LINE;
}
else if(Character.isJavaIdentifierPart(prev))
{
command = Character.isUpperCase(next) ? APPEND_WITH_LOW_LINE : APPEND_UPPER_CASED;
}
else
{
command = APPEND_UPPER_CASED_WITH_LOW_LINE;
}
}
else
{
command = IGNORE;
}
return command;
}
};
}
}