/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2001,2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
// ServiceLocationAttribute.java : Class for attributes in SLP.
// Author: James Kempf, Erik Guttman
//
/**
* The ServiceLocationAttribute class models SLP attributes.
*
* @author James Kempf, Erik Guttman
*/
implements Serializable {
// Characters to escape.
// Whitespace chars.
// For character escaping.
// Bad tag characters.
// For identifying booleans.
//
// Package accessable fields.
//
// For V1 compatibility subclass.
/**
* Construct a service location attribute.
*
* @param id The attribute name
* @param values_in Vector of one or more attribute values. Vector
* contents must be uniform in type and one of
* Integer, String, Boolean, or byte[]. If the attribute
* is a keyword attribute, then values_in should be null.
* @exception IllegalArgumentException Thrown if the
* vector contents is not of the right type or
* an argument is null or syntactically incorrect.
*/
throws IllegalArgumentException {
verifyValueTypes(values, false);
}
}
/**
* Construct a service location attribute from a parenthesized expression.
* The syntax is:
*
* exp = "(" id "=" value-list ")" | keyword
* value-list = value | value "," value-list
*
*
* @param exp The expression
* @param dontTypeCheck True if multivalued booleans and vectors
* of varying types are allowed.
* @exception ServiceLocationException If there are any syntax errors.
*/
throws ServiceLocationException {
"null_string_parameter",
}
// If start and end paren, then parse out assignment.
"=",
true);
try {
// Get the tag.
id =
throw
"null_id",
}
// Gather the rest.
// Parse the comma separated list.
// Convert to objects.
for (i = 0; i < n; i++) {
// Need to determine which type to use.
values.setElementAt(o, i);
}
} catch (NoSuchElementException ex) {
throw
"assignment_syntax_err",
}
} else {
// Check to make sure there's no parens.
throw
"assignment_syntax_err",
}
// Unescape the keyword.
}
}
throws ServiceLocationException {
// If it can be converted into an integer, then convert it.
try {
} catch (NumberFormatException ex) {
// Wasn't an integer. Try boolean.
} else {
// Process the string to remove escapes.
// If it begins with the opaque prefix, treat it as an
// opaque.
} else {
o = unescapeAttributeString(val, false);
}
}
}
return o;
}
//
// Property accessors.
//
/**
* @return A vector of attribute values, or null if the attribute is
* a keyword attribute. If the attribute is single-valued, then
* the vector contains only one object.
*
*/
return null; // keyword case.
}
// Need to process Opaques.
for (i = 0; i < n; i++) {
if (o instanceof Opaque) {
}
ret.setElementAt(o, i);
}
return ret;
}
/**
* @return The attribute name.
*/
return id;
}
/**
* Return an escaped version of the id parameter , suitable for inclusion
* in a query.
*
* @param str The string to escape as an id.
* @return The string with any reserved characters escaped.
* @exception IllegalArgumentException Thrown if the
* string contains bad tag characters.
*/
throws IllegalArgumentException {
try {
} catch (ServiceLocationException ex) {
}
return ret;
}
/**
* Return an escaped version of the value parameter, suitable for inclusion
* in a query. Opaques are stringified.
*
* @param val The value to escape.
* @return The stringified value.
* @exception IllegalArgumentException Thrown if the object is not
* one of byte[], Integer, Boolean, or String.
*/
throws IllegalArgumentException {
// Check type first.
// Make Opaque out of byte[].
if (val instanceof byte[]) {
}
return escapeValueInternal(val);
}
// Check type to make sure it's OK.
throw
new Object[0]));
}
throw
new Object[0]));
}
}
// We know the value's type is OK, so just escape it.
String s;
// Escape any characters needing it.
try {
} catch (ServiceLocationException ex) {
throw
}
} else {
}
return s;
}
//
// Methods for dealing with the type of attribute values.
//
// Verify the types of incoming attributes.
protected void
// Make sure the types of objects passed in are acceptable
// and that all objects in the vector have the same type.
for (i = 0; i < n; i++) {
if (i == 0) {
throw
new Object[0]));
}
// If it's a boolean and there's more than one, signal error
// unless multivalued booleans are allowed.
throw
new Object[0]));
}
// If it's a byte array, create a Opaque object.
if (obj instanceof byte[]) {
// If it's a string and looks like "1" or "true", then
// append a space onto the end.
try {
}
} catch (ServiceLocationException ex) {
// Ignore for now.
}
}
}
}
//
// Methods for externalizing attributes.
//
/**
* Externalize the attribute into a string that can be written
* to a byte stream. Includes escaping any characters that
* need to be escaped.
*
* @return String with attribute's external representation.
* @exception ServiceLocationException Thrown if the
* string contains unencodable characters.
*/
throws ServiceLocationException {
return escapeAttributeString(id, true);
}
Object o = e.nextElement();
s = escapeValueInternal(o);
v.addElement(s);
}
new StringBuffer("(" +
escapeAttributeString(id, true) +
"=");
}
//
// Escaping and unescaping strings.
//
/**
* Escape any escapable characters to a 2 character escape
* in the attribute string.
*
* @param string The String.
* @param badTag Check for bad tag characters if true.
* @return The escaped string.
* @exception ServiceLocationException Thrown if the string
* contains a character that can't be encoded.
*/
boolean badTag)
throws ServiceLocationException {
for (i = 0; i < n; i++) {
// Check for bad tag characters first.
throw
"bad_id_char",
}
// Escape if the character is reserved.
if (canEscape(c)) {
// Pad with zero if less than 2 characters.
}
} else {
}
}
}
/**
* Convert any 2 character escapes to the corresponding characters.
*
* @param string The string to be processed.
* @param badTag Check for bad tag characters if true.
* @return The processed string.
* @exception ServiceLocationException Thrown if an escape
* is improperly formatted.
*/
boolean badTag)
throws ServiceLocationException {
// Process escapes.
for (i = 0; i < n; i++) {
// Check for escaped characters.
if (c == ESCAPE) {
// Get the next two characters.
if (i >= n - 2) {
throw
"nonterminating_escape",
}
i++;
i++;
// Check whether it's reserved.
if (!canEscape(c)) {
throw
"char_not_reserved_attr",
}
} else {
// Check whether the character is reserved.
if (isReserved(c)) {
throw
"reserved_not_escaped",
}
}
// If we need to check for a bad tag character, do so now.
throw
"bad_id_char",
}
}
}
// Return true if the character c can be escaped.
private static boolean canEscape(char c) {
}
// Return true if the character c is reserved.
private static boolean isReserved(char c) {
}
/**
* Return a string of integers giving the character's encoding in
* the character set passed in as encoding.
*
* @param c The character to escape.
* @return The character as a string of integers for the encoding.
*/
byte[] b = null;
try {
} catch (UnsupportedEncodingException ex) {
}
int code = 0;
// Assemble the character code.
if (b.length > 3) {
"illegal_utf8",
}
if (b.length > 1) {
}
if (b.length > 2) {
}
return str;
}
/**
* Unescape the character encoded as the string.
*
* @param ch The character as a string of hex digits.
* @return The character.
* @exception ServiceLocationException If the characters can't be
* converted into a hex string.
*/
throws ServiceLocationException {
int code = 0;
try {
} catch (NumberFormatException ex) {
throw
"not_a_character",
}
// Convert to bytes.
byte b[] = null;
// We allow illegal UTF8 encoding so we can decode byte arrays.
if (b3 != 0) {
b = new byte[3];
b[3] = b3;
b[2] = b2;
b[1] = b1;
b[0] = b0;
} else if (b2 != 0) {
b = new byte[3];
b[2] = b2;
b[1] = b1;
b[0] = b0;
} else if (b1 != 0) {
b = new byte[2];
b[1] = b1;
b[0] = b0;
} else {
b = new byte[1];
b[0] = b0;
}
// Make a string out of it.
try {
} catch (UnsupportedEncodingException ex) {
}
throw
"more_than_one",
}
}
/**
* Merge the values in newAttr into the attribute in the hashtable
* if a duplicate attribute, signal error if a type mismatch.
* Both the return vector and hashtable are updated, but the
* newAttr parameter is left unchanged.
*
* @param attr The ServiceLocationAttribute to check.
* @param attrHash A Hashtable containing the attribute tags as
* keys and the attributes as values.
* @param returns A Vector in which to put the attribute when done.
* @param dontTypeCheck If this flag is true, the value vector
* may have two booleans, may
* contain differently typed objects, or the
* function may merge a keyword and nonkeyword
* attribute.
* @exception ServiceLocationException Thrown if a type mismatch
* occurs.
*/
static void
boolean dontTypeCheck)
throws ServiceLocationException {
// Look up the attribute
// Don't try this trick with ServerAttributes!
!(newAttr instanceof ServerAttribute)),
"merge_servattr",
new Object[0]);
// If the attribute isn't in the hashtable, then add to
// vector and hashtable.
return;
}
// If both keywords, nothing further to do.
return;
}
// If we are not typechecking and one is keyword while the other
// is not, then simply merge in the nonkeyword. Otherwise,
// throw a type check exception.
if (dontTypeCheck) {
} else {
throw
"attribute_type_mismatch",
}
} else {
// Merge the two vectors. We type check against the attrVals
// vector, if we are type checking.
int i, n = attrNewVals.size();
for (i = 0; i < n; i++) {
// Check for type mismatch, throw exception if
// we are type checking.
throw
"attribute_type_mismatch",
}
// If we are typechecking, and we get two opposite
// booleans, we need to throw an exception.
throw
"boolean_incompat",
}
// Add the value if it isn't already there.
}
}
// Set the new attribute's values so they are the same as the old.
}
}
//
// Object overrides.
//
/**
* Return true if the object equals this attribute.
*/
if (!(o instanceof ServiceLocationAttribute)) {
return false;
}
if (o == this) {
return true;
}
// check equality of contents, deferring check of all values
return false;
}
return true;
}
return false;
}
return false;
}
// Check contents.
return false;
}
for (i = 0; i < n; i++) {
return false;
}
}
return true;
}
/**
* Return a human readable string for the attribute.
*/
s.append("=");
for (i = 0; i < n; i++) {
// Identify type.
if (i == 0) {
s.append(":");
} else {
s.append(",");
}
// Stringify object.
}
}
s.append(")");
return s.toString();
}
// Overrides Object.hashCode().
public int hashCode() {
}
}