package com.sun.slp;
import java.util.*;
import java.io.*;
class AttributeVerifier
extends Object
implements ServiceLocationAttributeVerifier {
private static final String ESC_HASH = "\\23";
private static final String HASH = "#";
private static final int TEMPLATE_ATTR_NO = 5;
private static final int SERVICE_MASK = 0x01;
private static final int VERSION_MASK = 0x02;
private static final int DESCRIPTION_MASK = 0x08;
private static final int URL_PATH_RULES_MASK = 0x10;
private static final int TEMPLATE_FOUND = (SERVICE_MASK |
VERSION_MASK |
DESCRIPTION_MASK |
URL_PATH_RULES_MASK);
private static final String INTEGER_TYPE = "integer";
private static final String STRING_TYPE = "string";
private static final String BOOLEAN_TYPE = "boolean";
private static final String OPAQUE_TYPE = "opaque";
private static final String KEYWORD_TYPE = "keyword";
static final String JAVA_STRING_TYPE =
"java.lang.String";
static final String JAVA_INTEGER_TYPE =
"java.lang.Integer";
static final String JAVA_BOOLEAN_TYPE =
"java.lang.Boolean";
static final String JAVA_OPAQUE_TYPE =
"[B";
private static final String TRUE_TOKEN = "true";
private static final String FALSE_TOKEN = "false";
private static final int FLAG_NO = 4;
private static final String MULTIPLE_FLAG = "m";
private static final String LITERAL_FLAG = "l";
private static final String EXPLICIT_FLAG = "x";
private static final String OPTIONAL_FLAG = "o";
private static final byte MULTIPLE_MASK = 0x01;
private static final byte LITERAL_MASK = 0x02;
private static final byte EXPLICIT_MASK = 0x04;
private static final byte OPTIONAL_MASK = 0x08;
private static final char TT_COMMA = ',';
private static final char TT_EQUALS = '=';
private static final char TT_FIELD = '#';
private static final char TT_ESCAPE = '\\';
private static final char TT_PERIOD = '.';
private static final char UPPER_START_CODE = 'A';
private static final char UPPER_END_CODE = 'Z';
private static final char LOWER_START_CODE = 'a';
private static final char LOWER_END_CODE = 'z';
private static final char NUMBER_START_CODE = '0';
private static final char NUMBER_END_CODE = '9';
private static final char EXTRA_CODE1 = '+';
private static final char EXTRA_CODE2 = '/';
private static final char PAD_CODE = '=';
private static final char LENGTH_SEPERATOR = ':';
private ServiceType serviceType;
private Locale locale;
private String version;
private String URLSyntax;
private String description;
private Hashtable attributeDescriptors = new Hashtable();
AttributeVerifier() {
}
void initialize(Reader r) throws ServiceLocationException {
StreamTokenizer tk = new StreamTokenizer(r);
initFieldChar(tk);
parseTemplate(tk);
}
void initializeAttributesOnly(Reader r)
throws ServiceLocationException {
StreamTokenizer tk = new StreamTokenizer(r);
initFieldChar(tk);
parseAttributes(tk);
}
public ServiceType getServiceType() {
return serviceType;
}
public Locale getLocale() {
return locale;
}
public String getVersion() {
return version;
}
public String getURLSyntax() {
return URLSyntax;
}
public String getDescription() {
return description;
}
public ServiceLocationAttributeDescriptor
getAttributeDescriptor(String attrId) {
return
(ServiceLocationAttributeDescriptor)
attributeDescriptors.get(attrId.toLowerCase());
}
public Enumeration getAttributeDescriptors() {
return ((Hashtable)attributeDescriptors.clone()).elements();
}
public void verifyAttribute(ServiceLocationAttribute attribute)
throws ServiceLocationException {
String id = attribute.getId().toLowerCase();
ServiceLocationAttributeDescriptor des =
(ServiceLocationAttributeDescriptor)attributeDescriptors.get(id);
if (des == null) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_no_attribute",
new Object[] { id });
}
String type = des.getValueType();
Vector vals = attribute.getValues();
if (des.getIsKeyword()) {
if (vals != null) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_not_null",
new Object[] { id });
}
} else {
int i, n;
if (vals == null) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_null",
new Object[] { id });
}
n = vals.size();
if (n > 1 && !des.getIsMultivalued()) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_not_multi",
new Object[] { id });
}
Vector av = null;
Enumeration en = des.getAllowedValues();
if (en.hasMoreElements()) {
av = new Vector();
while (en.hasMoreElements()) {
Object v = en.nextElement();
if (type.equals(JAVA_STRING_TYPE)) {
v = ((String)v).toLowerCase();
} else if (type.equals(JAVA_OPAQUE_TYPE)) {
v = new Opaque((byte[])v);
}
av.addElement(v);
}
}
String attTypeName = des.getValueType();
for (i = 0; i < n; i++) {
Object val = vals.elementAt(i);
String typeName = val.getClass().getName();
if (!typeName.equals(attTypeName)) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_type_mismatch",
new Object[] { id, typeName, attTypeName });
}
if (type.equals(JAVA_STRING_TYPE)) {
val = ((String)val).toLowerCase();
} else if (type.equals(JAVA_OPAQUE_TYPE)) {
val = new Opaque((byte[])val);
}
if (av != null && !av.contains(val)) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_not_allowed_value",
new Object[] {id, val});
}
}
}
}
public void verifyRegistration(Vector attributeVector)
throws ServiceLocationException {
Assert.nonNullParameter(attributeVector, "attributeVector");
if (attributeVector.size() <= 0) {
Enumeration en = attributeDescriptors.elements();
while (en.hasMoreElements()) {
ServiceLocationAttributeDescriptor attDesc =
(ServiceLocationAttributeDescriptor)en.nextElement();
if (!attDesc.getIsOptional()) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_missing_required",
new Object[] { attDesc.getId() });
}
}
} else {
int i, n = attributeVector.size();
Hashtable incoming = new Hashtable();
for (i = 0; i < n; i++) {
ServiceLocationAttribute attribute =
(ServiceLocationAttribute)attributeVector.elementAt(i);
String id = attribute.getId().toLowerCase();
if (incoming.get(id) != null) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_dup",
new Object[] { attribute.getId() });
}
verifyAttribute(attribute);
incoming.put(id, attribute);
}
Enumeration en = attributeDescriptors.elements();
while (en.hasMoreElements()) {
ServiceLocationAttributeDescriptor attDesc =
(ServiceLocationAttributeDescriptor)en.nextElement();
String attrId = attDesc.getId();
if (!attDesc.getIsOptional() &&
incoming.get(attrId.toLowerCase()) == null) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_missing_required",
new Object[] { attrId });
}
}
}
}
private void initForBase(StreamTokenizer tk) {
tk.resetSyntax();
tk.whitespaceChars((int)'\n', (int)'\n');
tk.lowerCaseMode(false);
}
private void initCommonToken(StreamTokenizer tk) {
tk.wordChars((int)'A', (int)'Z');
tk.wordChars((int)'a', (int)'z');
tk.wordChars((int)'0', (int)'9');
tk.wordChars((int)'&', (int)'&');
tk.wordChars((int)'*', (int)'*');
tk.wordChars((int)':', (int)':');
tk.wordChars((int)'-', (int)'-');
tk.wordChars((int)'_', (int)'_');
tk.wordChars((int)'$', (int)'$');
tk.wordChars((int)'+', (int)'+');
tk.wordChars((int)'@', (int)'@');
tk.wordChars((int)'.', (int)'.');
tk.wordChars((int)'|', (int)'|');
tk.wordChars((int)'<', (int)'<');
tk.wordChars((int)'>', (int)'>');
tk.wordChars((int)'~', (int)'~');
}
private void initIdChar(StreamTokenizer tk) {
initForBase(tk);
initCommonToken(tk);
tk.wordChars((int)'\\', (int)'\\');
tk.whitespaceChars((int)' ', (int)' ');
tk.whitespaceChars((int)'\t', (int)'\t');
tk.eolIsSignificant(false);
tk.lowerCaseMode(false);
}
private void initSchemeIdChar(StreamTokenizer tk) {
initForBase(tk);
tk.wordChars((int)'A', (int)'Z');
tk.wordChars((int)'a', (int)'z');
tk.wordChars((int)'0', (int)'9');
tk.wordChars((int)'-', (int)'-');
tk.wordChars((int)'+', (int)'+');
tk.wordChars((int)'.', (int)'.');
tk.wordChars((int)':', (int)':');
tk.whitespaceChars((int)' ', (int)' ');
tk.whitespaceChars((int)'\t', (int)'\t');
tk.eolIsSignificant(false);
tk.lowerCaseMode(false);
}
private void initStringItemChar(StreamTokenizer tk) {
initForBase(tk);
tk.wordChars((int)'\t', (int)'\t');
tk.wordChars((int)' ', (int)'"');
tk.wordChars((int)'$', (int)'+');
tk.wordChars((int)'-', (int)'/');
tk.wordChars((int)'0', (int)'9');
tk.wordChars((int)':', (int)':');
tk.wordChars((int)'<', (int)'@');
tk.wordChars((int)'A', (int)'Z');
tk.wordChars((int)'[', (int)'`');
tk.wordChars((int)'a', (int)'z');
tk.wordChars((int)'{', (int)'~');
tk.whitespaceChars((int)'\r', (int)'\r');
tk.whitespaceChars((int)'\n', (int)'\n');
tk.eolIsSignificant(true);
}
private void initIntItemChar(StreamTokenizer tk) {
initForBase(tk);
tk.wordChars((int)'0', (int)'9');
tk.wordChars((int)'-', (int)'-');
tk.wordChars((int)'+', (int)'+');
tk.whitespaceChars((int)' ', (int)' ');
tk.whitespaceChars((int)'\t', (int)'\t');
tk.whitespaceChars((int)'\r', (int)'\r');
tk.whitespaceChars((int)'\n', (int)'\n');
tk.eolIsSignificant(true);
}
private void initFieldChar(StreamTokenizer tk) {
initForBase(tk);
tk.wordChars((int)'\t', (int)'\t');
tk.wordChars((int)' ', (int)'/');
tk.wordChars((int)'0', (int)'9');
tk.wordChars((int)':', (int)'@');
tk.wordChars((int)'A', (int)'Z');
tk.wordChars((int)'[', (int)'`');
tk.wordChars((int)'a', (int)'z');
tk.wordChars((int)'{', (int)'~');
tk.whitespaceChars((int)'\r', (int)'\r');
tk.whitespaceChars((int)'\n', (int)'\n');
tk.eolIsSignificant(true);
}
private void parseTemplate(StreamTokenizer tk)
throws ServiceLocationException {
parseTemplateAttributes(tk);
parseAttributes(tk);
}
private void parseTemplateAttributes(StreamTokenizer tk)
throws ServiceLocationException {
int found = 0;
try {
do {
found = found | parseTemplateAttribute(tk, found);
} while (found != TEMPLATE_FOUND);
} catch (IOException ex) {
throw
new ServiceLocationException(
ServiceLocationException.INTERNAL_SYSTEM_ERROR,
"template_io_error",
new Object[] {Integer.toString(tk.lineno())});
}
}
private int parseTemplateAttribute(StreamTokenizer tk, int found)
throws ServiceLocationException, IOException {
int tt = tk.nextToken();
if (tt != StreamTokenizer.TT_WORD) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_assign_error",
new Object[] {Integer.toString(tk.lineno())});
}
StringReader rdr = new StringReader(tk.sval);
StreamTokenizer stk = new StreamTokenizer(rdr);
initIdChar(stk);
if ((tt = tk.nextToken()) == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
}
if (tt != StreamTokenizer.TT_EOL) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
if ((tt = stk.nextToken()) != StreamTokenizer.TT_WORD) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_missing_id",
new Object[] {Integer.toString(tk.lineno())});
}
String id = stk.sval;
boolean duplicate = false;
int mask = 0;
if ((tt = stk.nextToken()) != TT_EQUALS) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_missing_eq ",
new Object[] {Integer.toString(tk.lineno())});
}
if (id.equalsIgnoreCase(SLPTemplateRegistry.SERVICE_ATTR_ID)) {
if ((found & SERVICE_MASK) == 0) {
if ((tt = stk.nextToken()) != StreamTokenizer.TT_WORD) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_srv_type_err",
new Object[] {Integer.toString(tk.lineno())});
}
StreamTokenizer sttk =
new StreamTokenizer(new StringReader(stk.sval));
initSchemeIdChar(sttk);
if (sttk.nextToken() != StreamTokenizer.TT_WORD ||
!stk.sval.equals(sttk.sval)) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_srv_type_err",
new Object[] {Integer.toString(tk.lineno())});
}
String typeName = sttk.sval;
if (!typeName.startsWith(Defaults.SERVICE_PREFIX+":")) {
typeName = Defaults.SERVICE_PREFIX+":"+typeName;
}
serviceType = new ServiceType(typeName);
if ((tt = stk.nextToken()) != StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_srv_type_err",
new Object[] {Integer.toString(tk.lineno())});
}
mask = SERVICE_MASK;
} else {
duplicate = true;
}
} else if (id.equalsIgnoreCase(SLPTemplateRegistry.VERSION_ATTR_ID)) {
if ((found & VERSION_MASK) == 0) {
if ((tt = stk.nextToken()) != StreamTokenizer.TT_WORD) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_vers_err",
new Object[] {Integer.toString(tk.lineno())});
}
String version = stk.sval;
if (version.indexOf(TT_PERIOD) == -1) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_vers_mssing",
new Object[] {Integer.toString(tk.lineno())});
}
try {
Float.valueOf(version);
} catch (NumberFormatException ex) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_vers_err",
new Object[] {Integer.toString(tk.lineno())});
}
this.version = version;
if ((tt = stk.nextToken()) != StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_vers_err",
new Object[] {Integer.toString(tk.lineno())});
}
mask = VERSION_MASK;
} else {
duplicate = true;
}
} else if (id.equalsIgnoreCase(
SLPTemplateRegistry.DESCRIPTION_ATTR_ID)) {
if (stk.nextToken() != StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {Integer.toString(tk.lineno())});
}
if ((found & DESCRIPTION_MASK) == 0) {
String helpText = "";
do {
int ptt = tt;
tt = tk.nextToken();
if (tt == StreamTokenizer.TT_WORD) {
helpText = helpText + tk.sval + "\n";
} else if (tt == StreamTokenizer.TT_EOL) {
if (ptt == StreamTokenizer.TT_EOL) {
if (helpText.length() > 0) {
description = helpText;
}
tk.pushBack();
break;
}
} else if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
} while (true);
mask = DESCRIPTION_MASK;
} else {
duplicate = true;
}
} else if (id.equalsIgnoreCase(
SLPTemplateRegistry.SERVICE_URL_ATTR_ID)) {
if ((found & URL_PATH_RULES_MASK) == 0) {
String serviceURLGrammer = "";
int ic;
while ((ic = rdr.read()) != -1) {
serviceURLGrammer += (char)ic;
}
serviceURLGrammer += "\n";
tt = StreamTokenizer.TT_EOL;
do {
int ptt = tt;
tt = tk.nextToken();
if (tt == StreamTokenizer.TT_WORD) {
serviceURLGrammer = serviceURLGrammer + tk.sval + "\n";
} else if (tt == StreamTokenizer.TT_EOL) {
if (ptt == StreamTokenizer.TT_EOL) {
if (serviceURLGrammer.length() > 0) {
URLSyntax = serviceURLGrammer;
}
tk.pushBack();
break;
}
} else if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
} while (true);
mask = URL_PATH_RULES_MASK;
} else {
duplicate = true;
}
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_nontattribute_err",
new Object[] {Integer.toString(tk.lineno())});
}
if (duplicate) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_dup_def",
new Object[] {Integer.toString(tk.lineno())});
}
if ((tt = tk.nextToken()) != StreamTokenizer.TT_EOL) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {Integer.toString(tk.lineno())});
}
return mask;
}
private void parseAttributes(StreamTokenizer tk)
throws ServiceLocationException {
try {
do {
int tt = tk.nextToken();
if (tt == StreamTokenizer.TT_EOF) {
break;
}
tk.pushBack();
AttributeDescriptor attDesc = parseAttribute(tk);
checkDefaultValues(attDesc);
String attrId = attDesc.getId().toLowerCase();
if (attributeDescriptors.get(attrId) != null) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_dup_def",
new Object[] {Integer.toString(tk.lineno())});
}
attributeDescriptors.put(attrId, attDesc);
} while (true);
} catch (IOException ex) {
throw
new ServiceLocationException(
ServiceLocationException.INTERNAL_SYSTEM_ERROR,
"template_io_error",
new Object[] {Integer.toString(tk.lineno())});
}
}
private AttributeDescriptor
parseAttribute(StreamTokenizer tk) throws ServiceLocationException {
AttributeDescriptor attDesc = new AttributeDescriptor();
int lineno = 0;
try {
lineno = tk.lineno();
int tt = tk.nextToken();
if (tt != StreamTokenizer.TT_WORD) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {Integer.toString(tk.lineno())});
}
StreamTokenizer stk =
new StreamTokenizer(new StringReader(tk.sval));
initIdChar(stk);
parseId(stk, attDesc, lineno);
parseTypeAndFlags(stk, attDesc, lineno);
tt = tk.nextToken();
if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
}
if (tt != StreamTokenizer.TT_EOL) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
if (!attDesc.getIsKeyword()) {
String tok = "";
do {
int ptt = tt;
lineno = tk.lineno();
tt = tk.nextToken();
if (tt == StreamTokenizer.TT_WORD) {
String line = tk.sval.trim();
if (line.charAt(0) == TT_FIELD) {
if (tok.length() > 0) {
stk =
new StreamTokenizer(new StringReader(tok));
parseDefaultValues(stk, attDesc, lineno);
}
tk.pushBack();
break;
} else {
tok = tok + line;
}
} else if (tt == StreamTokenizer.TT_EOL) {
if (ptt == StreamTokenizer.TT_EOL) {
if (tok.length() > 0) {
stk =
new StreamTokenizer(new StringReader(tok));
parseDefaultValues(stk, attDesc, lineno);
}
return attDesc;
}
} else if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
} while (true);
} else {
attDesc.setDefaultValues(null);
attDesc.setAllowedValues(null);
if ((tt = tk.nextToken()) == StreamTokenizer.TT_EOL) {
return attDesc;
} else if (tt == StreamTokenizer.TT_WORD) {
String line = tk.sval.trim();
if (line.charAt(0) != TT_FIELD) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {Integer.toString(tk.lineno())});
} else {
tk.pushBack();
}
} else if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
}
String helpText = "";
do {
int ptt = tt;
lineno = tk.lineno();
tt = tk.nextToken();
if (tt == StreamTokenizer.TT_WORD) {
String line = tk.sval.trim();
if (line.charAt(0) == TT_FIELD) {
helpText =
helpText + line.substring(1) + "\n";
} else {
if (helpText.length() > 0) {
attDesc.setDescription(helpText);
}
tk.pushBack();
break;
}
} else if (tt == StreamTokenizer.TT_EOL ||
tt == StreamTokenizer.TT_EOF) {
if (ptt == StreamTokenizer.TT_EOL) {
if (helpText.length() > 0) {
attDesc.setDescription(helpText);
}
if (attDesc.getIsKeyword()) {
attDesc.setAllowedValues(null);
}
return attDesc;
} else if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
}
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
} while (true);
if (!attDesc.getIsKeyword()) {
String tok = "";
do {
int ptt = tt;
lineno = tk.lineno();
tt = tk.nextToken();
if (tt == StreamTokenizer.TT_WORD) {
tok = tok + tk.sval;
} else if (tt == StreamTokenizer.TT_EOL) {
if (ptt == StreamTokenizer.TT_EOL) {
if (tok.length() > 0) {
stk =
new StreamTokenizer(new StringReader(tok));
parseAllowedValues(stk, attDesc, lineno);
}
return attDesc;
}
} else if (tt == StreamTokenizer.TT_EOF) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_end_error",
new Object[] {Integer.toString(tk.lineno())});
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_unk_token",
new Object[] {Integer.toString(tk.lineno())});
}
} while (true);
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {Integer.toString(tk.lineno())});
}
} catch (IOException ex) {
throw
new ServiceLocationException(
ServiceLocationException.INTERNAL_SYSTEM_ERROR,
"template_io_error",
new Object[] {
Integer.toString(tk.lineno()),
ex.getMessage()});
}
}
private void checkDefaultValues(AttributeDescriptor attDesc)
throws ServiceLocationException {
if (attDesc.getIsKeyword()) {
return;
}
Enumeration init = attDesc.getDefaultValues();
Enumeration en = attDesc.getAllowedValues();
Vector allowed = new Vector();
String attDescType = attDesc.getValueType();
while (en.hasMoreElements()) {
Object allval = en.nextElement();
if (attDescType.equals(JAVA_STRING_TYPE)) {
allval = ((String)allval).toLowerCase();
} else if (attDescType.equals(JAVA_OPAQUE_TYPE)) {
allval = new Opaque((byte[])allval);
}
allowed.addElement(allval);
}
if (allowed.size() > 0) {
if (!init.hasMoreElements()) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_no_init",
new Object[] {attDesc.getId()});
}
Object val = null;
while (init.hasMoreElements()) {
Object test = init.nextElement();
val = test;
if (attDescType.equals(JAVA_STRING_TYPE)) {
test = ((String)test).toLowerCase();
} else if (attDescType.equals(JAVA_OPAQUE_TYPE)) {
test = new Opaque((byte[])test);
}
if (allowed.indexOf(test) != -1) {
return;
}
}
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_wrong_init",
new Object[] {
val.toString(), attDesc.getId()});
}
}
private void parseId(StreamTokenizer tk,
AttributeDescriptor attDesc,
int baseLineno)
throws ServiceLocationException, IOException {
String id = parseWord(tk, baseLineno);
int tt = tk.nextToken();
if (tt != TT_EQUALS) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {
Integer.toString(tk.lineno() + baseLineno)});
}
id = unescapeHash(id);
id =
ServiceLocationAttribute.unescapeAttributeString(id, true);
attDesc.setId(id);
}
private void
parseTypeAndFlags(StreamTokenizer tk,
AttributeDescriptor attDesc,
int baseLineno)
throws ServiceLocationException, IOException {
int existingFlags = 0;
String type = parseWord(tk, baseLineno);
checkAndAddType(type, attDesc, tk.lineno() + baseLineno);
do {
if (tk.nextToken() == StreamTokenizer.TT_EOF) {
break;
} else {
tk.pushBack();
}
int lineno = tk.lineno();
String flag = parseWord(tk, baseLineno);
if (attDesc.getIsKeyword()) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {
Integer.toString(tk.lineno() + baseLineno)});
}
existingFlags =
existingFlags | checkAndAddFlag(flag,
existingFlags,
attDesc,
baseLineno + lineno);
} while (true);
}
private void parseDefaultValues(StreamTokenizer tk,
AttributeDescriptor attDesc,
int baseLineno)
throws ServiceLocationException, IOException {
Vector vals = parseValueList(tk, attDesc, baseLineno);
if (!attDesc.getIsMultivalued() && vals.size() > 1) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {
Integer.toString(tk.lineno() + baseLineno)});
}
attDesc.setDefaultValues(vals);
}
private void
parseAllowedValues(StreamTokenizer tk,
AttributeDescriptor attDesc,
int baseLineno)
throws ServiceLocationException, IOException {
Vector vals = parseValueList(tk, attDesc, baseLineno);
attDesc.setAllowedValues(vals);
}
private Vector parseValueList(StreamTokenizer stk,
AttributeDescriptor attDesc,
int baseLineno)
throws ServiceLocationException, IOException {
Vector req = new Vector();
String type = attDesc.getValueType();
if (type.equals(JAVA_STRING_TYPE) || type.equals(JAVA_OPAQUE_TYPE)) {
initStringItemChar(stk);
} else if (type.equals(JAVA_INTEGER_TYPE)) {
initIntItemChar(stk);
} else if (type.equals(JAVA_BOOLEAN_TYPE)) {
initIdChar(stk);
}
boolean wordRequired = true;
boolean syntaxError = false;
String reqTok = "";
int lineno = 0;
do {
int tt = stk.nextToken();
lineno = stk.lineno() + baseLineno;
if (tt == StreamTokenizer.TT_WORD) {
if (!wordRequired) {
syntaxError = true;
}
reqTok = stk.sval.trim();
Object reqVal = convertValue(type, reqTok, baseLineno);
req.addElement(reqVal);
wordRequired = false;
} else if (tt == StreamTokenizer.TT_EOF) {
if (wordRequired) {
syntaxError = true;
}
break;
} else if (tt == TT_COMMA) {
if (wordRequired) {
syntaxError = true;
break;
}
wordRequired = true;
} else {
syntaxError = true;
break;
}
} while (true);
if (syntaxError) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_attr_syntax",
new Object[] {Integer.toString(lineno)});
}
return req;
}
private void checkAndAddType(String type,
AttributeDescriptor attDesc,
int lineno)
throws ServiceLocationException {
if (type.equalsIgnoreCase(STRING_TYPE)) {
attDesc.setValueType(JAVA_STRING_TYPE);
} else if (type.equalsIgnoreCase(INTEGER_TYPE)) {
attDesc.setValueType(JAVA_INTEGER_TYPE);
} else if (type.equalsIgnoreCase(BOOLEAN_TYPE)) {
attDesc.setValueType(JAVA_BOOLEAN_TYPE);
} else if (type.equalsIgnoreCase(OPAQUE_TYPE)) {
attDesc.setValueType(JAVA_OPAQUE_TYPE);
} else if (type.equalsIgnoreCase(KEYWORD_TYPE)) {
attDesc.setIsKeyword(true);
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_not_slp_type",
new Object[] {Integer.toString(lineno)});
}
}
private int checkAndAddFlag(String flag,
int matched,
AttributeDescriptor attDesc,
int lineno)
throws ServiceLocationException {
boolean duplicate = false;
if (flag.equalsIgnoreCase(MULTIPLE_FLAG)) {
if ((matched & MULTIPLE_MASK) != 0) {
duplicate = true;
} else {
if (attDesc.getValueType().equals(JAVA_BOOLEAN_TYPE)) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_boolean_multi",
new Object[] {Integer.toString(lineno)});
}
attDesc.setIsMultivalued(true);
return MULTIPLE_MASK;
}
} else if (flag.equalsIgnoreCase(LITERAL_FLAG)) {
if ((matched & LITERAL_MASK) != 0) {
duplicate = true;
} else {
attDesc.setIsLiteral(true);
return LITERAL_MASK;
}
} else if (flag.equalsIgnoreCase(EXPLICIT_FLAG)) {
if ((matched & EXPLICIT_MASK) != 0) {
duplicate = true;
} else {
attDesc.setRequiresExplicitMatch(true);
return EXPLICIT_MASK;
}
} else if (flag.equalsIgnoreCase(OPTIONAL_FLAG)) {
if ((matched & OPTIONAL_MASK) != 0) {
duplicate = true;
} else {
attDesc.setIsOptional(true);
return OPTIONAL_MASK;
}
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_invalid_attr_flag",
new Object[] {Integer.toString(lineno)});
}
if (duplicate) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_dup_attr_flag",
new Object[] {Integer.toString(lineno)});
}
return 0;
}
private String parseWord(StreamTokenizer tk, int baseLineno)
throws ServiceLocationException, IOException {
int tt = tk.nextToken();
if (tt == StreamTokenizer.TT_WORD) {
return (tk.sval);
} else {
String errorToken = "";
if (tt == StreamTokenizer.TT_NUMBER) {
errorToken = Double.toString(tk.nval);
} else if (tt == StreamTokenizer.TT_EOL) {
errorToken = "<end of line>";
} else if (tt == StreamTokenizer.TT_EOF) {
errorToken = "<end of file>";
} else {
errorToken = (Character.valueOf((char)tt)).toString();
}
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_invalid_tok",
new Object[] {
Integer.toString(tk.lineno() + baseLineno)});
}
}
private Object convertValue(String type,
String reqTok,
int lineno)
throws ServiceLocationException,
IOException {
Object reqVal = null;
if (type.equals(JAVA_STRING_TYPE)) {
reqTok = unescapeHash(reqTok);
reqVal =
ServiceLocationAttribute.unescapeAttributeString(reqTok,
false);
} else if (type.equals(JAVA_INTEGER_TYPE)) {
try {
reqVal = Integer.valueOf(reqTok);
} catch (NumberFormatException ex) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_expect_int",
new Object[] {
Integer.toString(lineno), reqTok });
}
} else if (type.equals(JAVA_BOOLEAN_TYPE)) {
if (reqTok.equalsIgnoreCase(TRUE_TOKEN)) {
reqVal = Boolean.valueOf(true);
} else if (reqTok.equalsIgnoreCase(FALSE_TOKEN)) {
reqVal = Boolean.valueOf(false);
} else {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"template_expect_bool",
new Object[] {
Integer.toString(lineno), reqTok});
}
} else if (type.equals(JAVA_OPAQUE_TYPE)) {
reqVal = Opaque.unescapeByteArray(reqTok);
} else {
Assert.slpassert(false,
"template_attr_desc",
new Object[0]);
}
return reqVal;
}
private String unescapeHash(String str) {
StringBuffer buf = new StringBuffer();
int len = ESC_HASH.length();
int i, j = 0;
for (i = str.indexOf(ESC_HASH, j);
i != -1;
i = str.indexOf(ESC_HASH, j)) {
buf.append(str.substring(j, i));
buf.append(HASH);
j = i + len;
}
len = str.length();
if (j < len) {
buf.append(str.substring(j, len));
}
return buf.toString();
}
}