package edu.stanford.rt.parser;
//imports Apache Xerces API
import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.InputSource;
import org.w3c.dom.*;
// imports XML Security PublicKey api
import org.apache.xml.security.keys.content.keyvalues.DSAKeyValue;
import org.apache.xml.security.keys.content.keyvalues.RSAKeyValue;
import org.apache.xml.security.exceptions.XMLSecurityException;
import java.io.*;
import java.util.*;
import edu.stanford.rt.datatype.*;
import edu.stanford.rt.credential.*;
import edu.stanford.rt.util.*;
/**
* @author Ninghui Li, Sandra Qiu
*
* RTParser parses a XML-format CredentialStore document and transforms
* the various elements into their corresponding Java objects.
*/
public class RTParser implements TagNameConstants, Constants
{
/** The DOM parser this transformer uses*/
private DOMParser parser;
/**
* Constructor for RTParser.
*/
public RTParser() throws Exception
{
parser = new DOMParser();
parser.setFeature(
"http://apache.org/xml/features/validation/schema",
true);
parser.setErrorHandler(new ParsingErrorHandler());
}
/**
* Method createSystemDomain.
* The method for creating system domain.
* *** Only useful for our parser.
* @return ApplicationDomain
* @throws Exception
*/
public synchronized ApplicationDomain createSystemDomain()
throws Exception
{
String spec =
System.getProperty("edu.stanford.rt.SystemDomain",
"C:\\rtml\\schemas\\systemSpec.xml");
return parseSystemDomain(new FileInputStream(new File(spec)));
}
/**
* Method parseSystemDomain.
* parses system domain from a XML input source, typically a
* XML file. The system domain element in the source should be
* the root element.
* @param in
* @return ApplicationDomain
* @throws Exception
*/
public synchronized ApplicationDomain parseSystemDomain(InputStream in)
throws Exception
{
parser.parse(new InputSource(in));
Document document = parser.getDocument();
Element root = document.getDocumentElement();
return transformSystemDomain(root);
}
/**
* Method parseSystemDomain.
* parses system domain from a XML input source, typically a
* XML file. The system domain element in the source should be
* the root element.
* @param in
* @return CredentialDomain
* @throws Exception
*/
public synchronized CredentialDomain
parseCredentialDomain(InputStream in, RTContext context)
throws Exception
{
parser.parse(new InputSource(in));
Document document = parser.getDocument();
Element root = document.getDocumentElement();
return transformCredential(root, context);
}
/**
* Method transformSystemDomain.
* transforms the XML element to the built-in system
* ApplicationDomain
.
* @param root
* XML element of system domain.
* @return ApplicationDomain
* @throws DomainSpecException
*/
public synchronized ApplicationDomain transformSystemDomain(Element root)
throws DomainSpecException
{
if (!root.getTagName().equals(APP_DOMAIN_SPEC))
throw new DomainSpecException("Not an ApplicationDomainSpecification element.");
String uri = root.getAttribute(URI);
ApplicationDomain spec =
new ApplicationDomain(uri, true, null);
String hashID = root.getAttribute(ID);
if (hashID.length() == 0)
{
// compute the hashID ourselves.
// hashID = getHash(spec);
}
HashID id = new HashID(HashID.APPLICATION_DOMAIN, hashID);
spec.setHashID(id);
// Add XML schema date types
spec.addType(new TimeType("dateTime"));
spec.addType(new TimeType("date"));
spec.addType(new TimeType("time"));
spec.addType(new TimeType("gYear"));
spec.addType(new TimeType("gYearMonth"));
spec.addType(new TimeType("gMonth"));
spec.addType(new TimeType("gMonthDay"));
spec.addType(new TimeType("gDay"));
Element[] elements = RTParser.getChildElements(root);
for (int i = 0; i < elements.length; i++)
{
Element childEle = elements[i];
String childName = childEle.getTagName();
if (childName.equals(INTEGER_TYPE))
{
IntegerType intType =
transformIntegerTypeDeclaration(childEle);
spec.addType(intType);
}
else if (childName.equals(DECIMAL_TYPE))
{
DecimalType decimalType =
transformDecimalTypeDeclaration(childEle);
spec.addType(decimalType);
}
else if (childName.equals(STRING_TYPE))
{
StringType stringType =
transformStringTypeDeclaration(childEle);
spec.addType(stringType);
}
else if (childName.equals(ENUM_TYPE))
{
EnumType enumType =
transformEnumTypeDeclaration(childEle, spec);
spec.addType(enumType);
}
else if (childName.equals(RECORD_TYPE))
{
RecordType recordType =
transformRecordTypeDeclaration(childEle, spec);
spec.addType(recordType);
}
else if (childName.equals(TREE_TYPE))
{
TreeType treeType =
transformTreeTypeDeclaration(childEle);
spec.addType(treeType);
}
} // end of for()...
spec.setComplete();
return spec;
}
/**
* Method getFirstChildElement.
Returns the first child element of ELEMENT_NODE type for the
given parent element.
* @param parent
* @return Element
*/
static public Element getFirstChildElement(Element parent)
{
Element ele = null;
NodeList nodes = parent.getChildNodes();
int n = nodes.getLength();
for (int i = 0; i < n; i++)
{
Node node = nodes.item(i);
short type = node.getNodeType();
if (type != org.w3c.dom.Node.ELEMENT_NODE)
continue;
ele = (Element) node;
break;
}
return ele;
}
/**
* Method getFirstChildElementByTagName.
* returns the first child element with the given tag name.
* @param parent
* @param tagName
* @return Element
*/
/**
*/
static public Element getFirstChildElementByTagName(
Element parent,
String tagName)
{
Element ele = null;
NodeList nodes = parent.getElementsByTagName(tagName);
ele = (Element) nodes.item(0);
return ele;
}
/**
* Method getChildElements.
* returns an array of child elements of ELEMNENT_NODE type.
* @param parent
* @return Element[]
*/
static public Element[] getChildElements(Element parent)
{
ArrayList elements = new ArrayList();
NodeList nodes = parent.getChildNodes();
int n = nodes.getLength();
for (int i = 0; i < n; i++)
{
Node node = nodes.item(i);
short type = node.getNodeType();
if (type != org.w3c.dom.Node.ELEMENT_NODE)
continue;
elements.add((Element) node);
}
// put into an array of Elements.
int size = elements.size();
Element[] eleArray = new Element[size];
for (int i = 0; i < size; i++)
{
eleArray[i] = (Element) elements.get(i);
}
return eleArray;
}
/**
* Method parseCredentialStore.
* parses credential store from an XML input source, typically an
* XML file. The CredentialStore
element should be a
* root element.
* @param in
* @param rtContext
* the context in which the parsing occurs.
* @param credentialStore
* the credential store being constructed.
* @throws DomainSpecException
*/
public synchronized void parseCredentialStore(
InputStream in,
RTContext rtContext,
CredentialStore credentialStore)
throws Exception
{
parser.parse(new InputSource(in));
Document document = parser.getDocument();
Element root = document.getDocumentElement();
transformCredentialStore(root, rtContext, credentialStore);
}
/**
* Method transformCredentialStore.
* @param root
* the XML element of credential store
* @param rtContext
* @param credentialStore
* @throws DomainSpecException
* @throws CredException
*/
public synchronized void transformCredentialStore(
Element root,
RTContext rtContext,
CredentialStore credentialStore)
throws DomainSpecException, CredException
{
String rootTag = root.getTagName();
if (!rootTag.equals(CREDENTIAL_STORE))
{
throw new DomainSpecException("Not a CredentialStore document.");
}
Element[] elements = getChildElements(root);
for (int i = 0; i < elements.length; i++)
{
String tag = elements[i].getTagName();
if (tag.equals(APP_DOMAIN_SPEC))
{
ApplicationDomain spec =
transformDomain(elements[i], rtContext);
HashID id = spec.getHashID();
rtContext.addApplicationDomain(id, spec);
}
else if (tag.equals(PRINCIPAL_INFO))
{
// TODO
// rtContext.addPrincipal(PublickeyPrincipal, PublicKeyPrincipalInfo);
}
else if (tag.equals(CREDENTIAL))
{
CredentialDomain credentialDomain =
transformCredential(elements[i], rtContext);
HashID id = credentialDomain.getHashID();
credentialStore.addCredentialDomain(
id,
credentialDomain);
}
// else if (tag.equals(ACCESS_RULE))
// {
// CredentialDomain accessRuleDomain =
// transformAccessRule(elements[i], rtContext);
// HashID id = accessRuleDomain.getHashID();
// credentialStore.addCredentialDomain(
// id,
// accessRuleDomain);
// }
}
}
/**
* Method transformDomain.
* parses non-system ApplicationDomain
.
* @param ele
* the ApplicationDomain
element
* @param rtContext
* the context in which the transformation occurs.
* @return ApplicationDomain
* @throws DomainSpecException
*/
public synchronized ApplicationDomain transformDomain(
Element ele,
RTContext rtContext)
throws DomainSpecException
{
if (!ele.getTagName().equals(APP_DOMAIN_SPEC))
throw new DomainSpecException("Not an ApplicationDomainSpecification element");
String uri = ele.getAttribute(URI);
// if (uri.length() == 0)
// throw new DomainSpecException(
// missing_attr_value + "'uri'");
ApplicationDomain spec =
new ApplicationDomain(uri, false, rtContext);
String hashID = ele.getAttribute(ID);
if (hashID.length() == 0)
{
// compute the hashID ourselves.
// hashID = getHash(spec);
}
HashID id = new HashID(HashID.APPLICATION_DOMAIN, hashID);
spec.setHashID(id);
Element[] elements = getChildElements(ele);
for (int i = 0; i < elements.length; i++)
{
Element childEle = elements[i];
String childName = childEle.getTagName();
if (childName.equals(IMPORT_DOMAIN))
{
String name = childEle.getAttribute(NAME);
if (name.length() == 0)
throw new DomainSpecException(
missing_attr_value + "'name'");
String importedUri = childEle.getAttribute(URI);
String idref = childEle.getAttribute(IDREF);
if (idref.length() == 0)
throw new DomainSpecException(
missing_attr_value + "'idref'");
ApplicationDomain importedDomain =
locateDomain(idref, importedUri, rtContext);
spec.importDomain(name, importedDomain);
}
else if (childName.equals(INTEGER_TYPE))
{
IntegerType intType =
transformIntegerTypeDeclaration(childEle);
spec.addType(intType);
}
else if (childName.equals(DECIMAL_TYPE))
{
DecimalType decimalType =
transformDecimalTypeDeclaration(childEle);
spec.addType(decimalType);
}
else if (childName.equals(ENUM_TYPE))
{
EnumType enumType =
transformEnumTypeDeclaration(childEle, spec);
spec.addType(enumType);
}
else if (childName.equals(STRING_TYPE))
{
StringType stringType =
transformStringTypeDeclaration(childEle);
spec.addType(stringType);
}
else if (childName.equals(RECORD_TYPE))
{
RecordType recordType =
transformRecordTypeDeclaration(childEle, spec);
spec.addType(recordType);
}
else if (childName.equals(TREE_TYPE))
{
TreeType treeType =
transformTreeTypeDeclaration(childEle);
spec.addType(treeType);
}
else if (childName.equals(PRINCIPAL_TYPE))
{
// This element specifies the principal type for the entire system
// Later on, the principal value can be checked against the type
// defined here.
SimpleType prinType =
transformPrincipalTypeDeclaration(childEle, spec);
spec.setPrincipalType(prinType);
}
else if (childName.equals(ROLE_DECLARATION))
{
RoleDeclaration role =
transformRoleDeclaration(childEle, spec);
spec.addRole(role);
}
} //end of for( )....
spec.setComplete();
return spec;
} //==== End of parseDomainSpec()
/**
Parses non-system domain specification object from a file pointed by the
given uri.
*/
// private void parseDomainSpec(String uri)
// {
// DomainSpecification spec = null;
// try
// {
// DOMParser parser = new DOMParser();
// parser.setFeature(
// "http://apache.org/xml/features/validation/schema",
// true);
// parser.parse(new InputSource(new FileInputStream(new File(uri))));
// Document doc = parser.getDocument();
// transform(doc);
// }
// catch (SAXException e)
// {
// System.out.println("error in setting up parser feature");
// }
// catch (Exception ex)
// {
// ex.printStackTrace();
// }
// }
//
// private void transform(Document document) throws Exception
// {
// Element root = document.getDocumentElement();
// String rootTag = root.getTagName();
//
// }
/**
* Method locateDomain.
* @param rtContext
* @param idref
* the hash value of the target
* ApplicationDomainSpecification
object.
* @param uri
* @return ApplicationDomain
* @throws DomainSpecException
* if cannot find the domain by the given idref.
*/
private ApplicationDomain locateDomain(
String idref,
String uri,
RTContext rtContext)
throws DomainSpecException
{
ApplicationDomain spec = null;
if (!rtContext.hasDomainWithID(idref))
{
//TODO: load domain from given uri, which is optional.
//parseDomainSpec(uri);
//spec = (DomainSpecification)applicationDomains.get(uri);
throw new DomainSpecException(
"Cannot find domain with id '" + idref + "'.");
}
else
{
spec = rtContext.getApplicationDomain(idref);
}
if (!spec.isComplete())
{
throw new DomainSpecException("Circular Dependency");
}
return spec;
}
/*###########################################################
#####
##### Parsing DateType Declaration in DomainSpecification
#####
#############################################################*/
/**
* Method transformIntegerTypeDeclaration.
*
* Parses IntegerType declaration in ADSD.
* Returns an IntegerType object by parsing element:
<IntegerType name="" min="" max=""/>* @param ele * @return IntegerType * @throws DomainSpecException */ private IntegerType transformIntegerTypeDeclaration(Element ele) throws DomainSpecException { if (!ele.getTagName().equals(INTEGER_TYPE)) throw new DomainSpecException("Not an IntegerType element"); String name = ele.getAttribute(NAME); String minStr = ele.getAttribute(MIN); String maxStr = ele.getAttribute(MAX); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); if (minStr.length() == 0) throw new DomainSpecException( missing_attr_value + "'min'"); if (maxStr.length() == 0) throw new DomainSpecException( missing_attr_value + "'max'"); long min = Long.parseLong(minStr); long max = Long.parseLong(maxStr); // RTUtil.debugInfo("name = " + name); // RTUtil.debugInfo("min = " + ele.getAttribute(MIN)); // RTUtil.debugInfo("max = " + ele.getAttribute(MAX)); // RTUtil.debugInfo("base = " + ele.getAttribute(BASE)); // RTUtil.debugInfo("step = " + ele.getAttribute(STEP)); // RTUtil.debugInfo("includeMin = " + ele.getAttribute(INCLUDE_MIN)); // RTUtil.debugInfo("includeMax = " + ele.getAttribute(INCLUDE_MAX)); boolean includeMin = RTUtil.parseBoolean(ele.getAttribute(INCLUDE_MIN), true); boolean includeMax = RTUtil.parseBoolean(ele.getAttribute(INCLUDE_MAX), true); long base = RTUtil.parseLong(ele.getAttribute(BASE), 0); long step = RTUtil.parseLong(ele.getAttribute(STEP), 1); return new IntegerType( name, min, max, includeMin, includeMax, base, step); } /** * Method transformDecimalTypeDeclaration.
<DecimalType name="" min="" max=""/>* @param ele * @return DecimalType * @throws DomainSpecException */ private DecimalType transformDecimalTypeDeclaration(Element ele) throws DomainSpecException { if (!ele.getTagName().equals(DECIMAL_TYPE)) throw new DomainSpecException("Not a DecimalType element"); // TODO throw new UnsupportedOperationException( no_support_for + "'DecimalType'"); } /** * Method transformStringTypeDeclaration.
<StringType name="" ignoreCase="false" ordered="false"/>* @param ele * @return StringType * @throws DomainSpecException */ private StringType transformStringTypeDeclaration(Element ele) throws DomainSpecException { if (!ele.getTagName().equals(STRING_TYPE)) throw new DomainSpecException("Not a StringType element"); String name = ele.getAttribute(NAME); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); boolean ignoreCase = RTUtil.parseBoolean(ele.getAttribute(IGNORE_CASE), false); boolean ordered = RTUtil.parseBoolean(ele.getAttribute(ORDERED), false); return new StringType(name, ignoreCase, ordered); } /** * Method transformEnumTypeDeclaration.
<EnumType name="" ignoreCase="false" ordered="false"/> <EnumValue>Monday</EnumValue> <EnumValue>Wednesday</EnumValue> <EnumValue>Friday</EnumValue> ... </EnumType>* @param ele * @param currentSpec * @return EnumType * @throws DomainSpecException */ private EnumType transformEnumTypeDeclaration( Element ele, DomainSpecification currentSpec) throws DomainSpecException { if (!ele.getTagName().equals(ENUM_TYPE)) throw new DomainSpecException("Not an EnumType element"); OrderedMap enumValues = new OrderedMap(String.class, Object.class); DataType valueType = null; String name = ele.getAttribute(NAME); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); boolean ignoreCase = RTUtil.parseBoolean(ele.getAttribute(IGNORE_CASE), false); boolean ordered = RTUtil.parseBoolean(ele.getAttribute(ORDERED), false); int size = RTUtil.parseInt(ele.getAttribute(SIZE), 0); Element[] elements = getChildElements(ele); for (int i = 0; i < elements.length; i++) { Element child = elements[i]; String childName = child.getTagName(); if (childName.equals(TYPE)) // nameRef type { // QQ: This element has been removed , as of 8/28/02 String domain = child.getAttribute(DOMAIN); String n = child.getAttribute(NAME); valueType = currentSpec.lookupType(domain, n); } else if (childName.equals(ENUM_VALUE)) { String value = transformEnumValue(null, child).getValue(); //RTUtil.debugInfo("value = " + value); enumValues.put(value, null); } } return new EnumType( name, valueType, enumValues, ignoreCase, ordered, size); } /** * Method transformTreeTypeDeclaration.
<TreeType name="DNSType" sparator="." order="rootLast"/>* @param ele * @return TreeType * @throws DomainSpecException */ private TreeType transformTreeTypeDeclaration(Element ele) throws DomainSpecException { if (!ele.getTagName().equals(TREE_TYPE)) throw new DomainSpecException("Not a TreeType element"); String name = ele.getAttribute(NAME); String separator = ele.getAttribute(SEPARATOR); String order = ele.getAttribute(ORDER); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); if (separator.length() == 0) throw new DomainSpecException( missing_attr_value + "'sepatator'"); if (order.length() == 0) throw new DomainSpecException( missing_attr_value + "'order'"); // RTUtil.debugInfo("name = " +name); // RTUtil.debugInfo("separator = " + separator); // RTUtil.debugInfo("order = " + order); return new TreeType( name, separator, order.equals(ROOT_FIRST)); } /** * Method transformRecordTypeDeclaration.
<RecordType name="record"> <Field name="field1"> <Type domain="" name=""/> </Field> <Field name="field2"> <Type domain="" name=""/> </Field> ... </RecordType>* @param ele * @param currentSpec * @return RecordType * @throws DomainSpecException */ private RecordType transformRecordTypeDeclaration( Element ele, DomainSpecification currentSpec) throws DomainSpecException { if (!ele.getTagName().equals(RECORD_TYPE)) throw new DomainSpecException("Not a RecordType element"); String name = ele.getAttribute(NAME); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); RTUtil.debugInfo( "parseRecordTypeDeclaration() > name = " + name); NodeList childNodes = ele.getElementsByTagName(FIELD); int size = childNodes.getLength(); if (size < 1) throw new DomainSpecException("No fields specified for the RecordType element."); OrderedMap fieldDeclarations = new OrderedMap(size, String.class, DataType.class); for (int i = 0; i < size; i++) { Element field = (Element) childNodes.item(i); String fieldName = field.getAttribute(NAME); if (fieldName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); Element typeRefEle = getFirstChildElementByTagName(field, TYPE); String typeName = typeRefEle.getAttribute(NAME); if (typeName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); String typeDomain = typeRefEle.getAttribute(DOMAIN); RTUtil.debugInfo("fieldName = " + fieldName); // RTUtil.debugInfo("typeName = " + typeName); // RTUtil.debugInfo("typeDomain = " + typeDomain); DataType fieldType = currentSpec.lookupType(typeDomain, typeName); fieldDeclarations.put(fieldName, fieldType); } return new RecordType(name, fieldDeclarations); } /** * Method transformPrincipalTypeDeclaration.
<PrincialType name="prinType"> <TypeRef domain="" name=""/> </PrincialType>* @param ele * @param currentSpec * @return SimpleType * @throws DomainSpecException */ private SimpleType transformPrincipalTypeDeclaration( Element ele, DomainSpecification currentSpec) throws DomainSpecException { if (!ele.getTagName().equals(PRINCIPAL_TYPE)) throw new DomainSpecException("Not a PrincipalType element"); Element typeRefEle = getFirstChildElementByTagName(ele, TYPE); String domain = typeRefEle.getAttribute(DOMAIN); String name = typeRefEle.getAttribute(NAME); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); return (SimpleType) currentSpec.lookupType(domain, name); } /** * Method transformRoleDeclaration.
<RoleDeclaration name="record"> <Parameter name="param1"> <Type domain="" name=""/> </Parameter> <Parameter name="param2"> <Type domain="" name=""/> </Parameter> ... </RoleDeclaration>* @param ele * @param currentSpec * the DomainSpecification in which the role is declared. * @return RoleDeclaration * @throws DomainSpecException */ private RoleDeclaration transformRoleDeclaration( Element ele, DomainSpecification currentSpec) throws DomainSpecException { if (!ele.getTagName().equals(ROLE_DECLARATION)) throw new DomainSpecException("Not a RoleDeclaration element"); String roleName = ele.getAttribute(NAME); if (roleName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); RTUtil.debugInfo( "parseRoleDeclaration > roleName = " + roleName); boolean isIdentity = RTUtil.parseBoolean(ele.getAttribute(IS_IDENTITY), false); int issuerT = RoleDeclaration.DEFAULT_ISSUER_TYPE; int subjectT = RoleDeclaration.DEFAULT_SUBJECT_TYPE; RoleDeclaration roleDeclaration = null; Element[] elements = getChildElements(ele); int n = elements.length; OrderedMap parameterDeclarations = new OrderedMap(n, String.class, DataType.class); for (int i = 0; i < n; i++) { Element childEle = elements[i]; String childName = childEle.getTagName(); if (childName.equals(RESTRICTION)) { Element baseRoleEle = getFirstChildElementByTagName( childEle, BASE_ROLE); String baseRoleName = baseRoleEle.getAttribute(NAME); if (baseRoleName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); String baseRoleDomain = baseRoleEle.getAttribute(DOMAIN); // get base role RoleDeclaration baseRole = currentSpec.lookupRoleDeclaration( baseRoleDomain, baseRoleName); // get new parameters NodeList paramNodes = childEle.getElementsByTagName(PARAMETER); OrderedMap newParameters = transformParameters(paramNodes, currentSpec); roleDeclaration = RoleDeclaration.createRestrictionRole( currentSpec, roleName, isIdentity, baseRole, newParameters); } else if (childName.equals(EXTENSION)) { Element baseRoleEle = getFirstChildElementByTagName( childEle, BASE_ROLE); String baseRoleName = baseRoleEle.getAttribute(NAME); if (baseRoleName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); String baseRoleDomain = baseRoleEle.getAttribute(DOMAIN); RoleDeclaration baseRole = currentSpec.lookupRoleDeclaration( baseRoleDomain, baseRoleName); NodeList paramNodes = childEle.getElementsByTagName(PARAMETER); OrderedMap newParameters = transformParameters(paramNodes, currentSpec); roleDeclaration = RoleDeclaration.createExtensionRole( currentSpec, roleName, isIdentity, baseRole, newParameters); } else if (childName.equals(PROJECTION)) { Element baseRoleEle = getFirstChildElementByTagName( childEle, BASE_ROLE); String baseRoleName = baseRoleEle.getAttribute(NAME); if (baseRoleName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); String baseRoleDomain = baseRoleEle.getAttribute(DOMAIN); RoleDeclaration baseRole = currentSpec.lookupRoleDeclaration( baseRoleDomain, baseRoleName); NodeList paramNodes = childEle.getElementsByTagName(PARAMETER); int num = paramNodes.getLength(); String[] newParamNames = new String[n]; for (int j = 0; j < num; j++) { Element e = (Element) paramNodes.item(j); newParamNames[j] = e.getAttribute(NAME); } roleDeclaration = RoleDeclaration.createProjectionRole( currentSpec, roleName, isIdentity, baseRole, newParamNames); } else if (childName.equals(PLAIN)) { String issuerTraces = childEle.getAttribute(ISSUER_TRACES); String subjectTraces = childEle.getAttribute(SUBJECT_TRACES); if (issuerTraces.length() != 0) { issuerT = ((Integer) (RoleDeclaration .issuerTracesTypes .get(issuerTraces.toLowerCase()))) .intValue(); } if (subjectTraces.length() != 0) { subjectT = ((Integer) (RoleDeclaration .subjectTracesTypes .get(subjectTraces.toLowerCase()))) .intValue(); } int dimension = RTUtil.parseInt( childEle.getAttribute(DIMENSION), 1); Element identityRoleEle = getFirstChildElementByTagName(childEle, IDENTITY); /* TODO String idBaseRoleName = identityRoleEle.getAttribute(NAME); if (idBaseRoleName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); String idBaseRoleDomain = identityRoleEle.getAttribute(DOMAIN); RoleDeclaration idBaseRole = currentSpec.lookupRoleDeclaration( idBaseRoleDomain, idBaseRoleName); */ NodeList paramNodes = childEle.getElementsByTagName(PARAMETER); OrderedMap newParameters = transformParameters(paramNodes, currentSpec); roleDeclaration = RoleDeclaration.createPlainRole( currentSpec, roleName, issuerT, subjectT, dimension, isIdentity, newParameters); } } // end of for loop return roleDeclaration; } /** * Method transformParameters.
Parameter
declarations in RoleDeclaration
element.
* @param nodes
* the list of Parameter
elements
* @return OrderedMap
* an OrderedMap of parameter declarations with parameter names as keys.
*/
private OrderedMap transformParameters(
NodeList nodes,
DomainSpecification currentSpec)
throws DomainSpecException
{
OrderedMap parameterDeclarations =
new OrderedMap(String.class, DataType.class);
int n = nodes.getLength();
for (int i = 0; i < n; i++)
{
Element childEle = (Element) nodes.item(i);
String paramName = childEle.getAttribute(NAME);
RTUtil.debugInfo("paramName = " + paramName);
Element typeRefEle =
getFirstChildElementByTagName(childEle, TYPE);
String domain = typeRefEle.getAttribute(DOMAIN);
//RTUtil.debugInfo("typeDomain = " + domain);
String name = typeRefEle.getAttribute(NAME);
//RTUtil.debugInfo("typeName = " + name);
DataType paramType = currentSpec.lookupType(domain, name);
parameterDeclarations.put(paramName, paramType);
}
return parameterDeclarations;
}
/*###########################################################
#####
##### Parsing Credential or AccessRule
#####
#############################################################*/
/**
* Method transformCredential.CredentialDomain
object by parsing element:
* * <Credential> * ... * </Credential> ** @param ele * @param rtContext * @return CredentialDomain * @throws DomainSpecException * @throws CredException */ public synchronized CredentialDomain transformCredential( Element ele, RTContext rtContext) throws DomainSpecException, CredException { if (!ele.getTagName().equals(CREDENTIAL)) throw new DomainSpecException("Not a Credential element."); String hashID = ele.getAttribute(ID); if (hashID.length() == 0) { //compute hashID } RTUtil.debugInfo("HashID = " + hashID); CredentialDomain credDomain = new CredentialDomain(ele, rtContext); HashID id = new HashID(HashID.CREDENTIAL_DOMAIN, hashID); credDomain.setHashID(id); Principal issuer = null; Element[] elements = getChildElements(ele); for (int i = 0; i < elements.length; i++) { Element child = elements[i]; String tagName = child.getTagName(); //RTUtil.debugInfo("***** tagName = " + tagName); if (tagName.equals(PREAMBLE)) { Element[] preambleElements = getChildElements(child); for (int j = 0; j < preambleElements.length; j++) { Element preambleChild = preambleElements[j]; String preambleChildTag = preambleChild.getTagName(); if (preambleChildTag.equals(IMPORT_DOMAIN)) // 0 or more { //short name for the imported domain in the scope of this credential. String name = preambleChild.getAttribute(NAME); if (name.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); RTUtil.debugInfo( "ImportDomain's name = " + name); String uri = preambleChild.getAttribute(URI); RTUtil.debugInfo( "ImportDomain's uri = " + uri); String idref = preambleChild.getAttribute(IDREF); if (idref.length() == 0) throw new DomainSpecException( missing_attr_value + "'idref'"); ApplicationDomain importedDomain = locateDomain(idref, uri, rtContext); credDomain.importDomain(name, importedDomain); } else if (preambleChildTag.equals(PRINCIPAL)) // 0 or more { // To improve readability, the principal, which could be quite long, // are included in the Preamble so that they can be referred to // in a compact way elsewhere in the credential by using PrincipalRef. RTUtil.debugInfo("parsing principle....."); transformPrincipalValue( preambleChild, credDomain); } } // end for().. } else if (tagName.equals(ISSUER)) { Element[] prinEle = getChildElements(child); if (prinEle.length != 1) throw new DomainSpecException( improper_sub_element_for + "'Issuer'"); issuer = transformPrincipalValue(prinEle[0], credDomain) .getValue(); credDomain.setIssuer(issuer); } // else if (tagName.equals(CREDENTIAL_IDENTIFIER)) // { // // TODO // throw new UnsupportedOperationException( // no_support_for + "'CredentialIdentifier'"); // } else if (tagName.equals(VALIDITY_TIME)) { //TODO //ValidityTime validityTime = parseValidityTime(child); //credDomain.setValidityTime(validityTime); } else if (tagName.equals(VALIDITY_RULE)) { // TODO throw new UnsupportedOperationException( no_support_for + "'ValidityRule'"); } else // ROLE_DEFINITION { RoleDefinition roleDef = transformRoleDefinition( issuer, credDomain, child); credDomain.addRoleDefinition(roleDef); } } //===== End of for(int i=0; i
A role definition may be one the the following elements, i.e. SimpleMember, SimpleContainment, LinkedContainment, IntersectionContainment, ProductContainment, ExclusiveProductContainment, SimpleDelegation, or AdvancedDelegation. Each role definition has a head and a body. The head part is defined by a HeadRoleTerm. The difference between the above 8 elements lies in the body part.
The product role definition represented by ProductContainment and
ExclusiveProductContainment has not been supported yet.
* @param issuer
* @param credDomain
* @param ele
* @return RoleDefinition
* @throws CredException
* @throws DomainSpecException
*/
private RoleDefinition transformRoleDefinition(
Principal issuer,
CredentialDomain credDomain,
Element ele)
throws CredException, DomainSpecException
{
RTUtil.debugInfo("parseRoleDefinition().... ");
String tag = ele.getTagName();
RTUtil.debugInfo("parseRoleDefinition()'s tag = " + tag);
if (!tag.equals(SIMPLE_MEMBER)
&& !tag.equals(SIMPLE_CONTAINMENT)
&& !tag.equals(LINKED_CONTAINMENT)
&& !tag.equals(INTERSECTION_CONTAINMENT)
&& !tag.equals(PRODUCT_CONTAINMENT)
&& !tag.equals(EXCLUSIVE_PRODUCT_CONTAINMENT)
&& !tag.equals(SIMPLE_DELEGATION)
&& !tag.equals(ADVANCED_DELEGATION))
throw new DomainSpecException("Not a proper role definition element");
RoleDefinition roleDefinition = null;
if (tag.equals(SIMPLE_DELEGATION)
|| tag.equals(ADVANCED_DELEGATION))
{
Element[] elements = getChildElements(ele);
if (elements.length < 2 || elements.length > 3)
throw new DomainSpecException(
improper_sub_element_for + "delegation role");
Element headElement = elements[0];
Element delegateToElement = elements[1];
Element controlElement = null; // optional
if (elements.length == 3)
controlElement = elements[2];
Role head =
new Role(
issuer,
transformRoleTerm(headElement, credDomain));
DelegationRole body =
transformDelegation(
issuer,
credDomain,
delegateToElement,
controlElement);
roleDefinition =
new RoleDefinition(credDomain, head, body);
}
else
{
Element[] elements = getChildElements(ele);
if (elements.length != 2)
throw new DomainSpecException(
improper_sub_element_for + "role definition");
Element headElement = elements[0];
Element bodyElement = elements[1];
Role head =
new Role(
issuer,
transformRoleTerm(headElement, credDomain));
PrincipalExpression body =
transformBody(issuer, credDomain, bodyElement);
roleDefinition =
new RoleDefinition(credDomain, head, body);
}
return roleDefinition;
}
/**
* Method transformBody.
* Returns a PrincipalExpression for the body of a role definition.
The body can be one of the following: PrincipalValue, RoleTerm,
ExternalRole, LinkedRole, Intersection, Product, or a Delegation.
The method handles all types of the role definition body except the
Delegation role body.
* @param issuer
* @param credDomain
* @param ele
* @return PrincipalExpression
* @throws CredException
* @throws DomainSpecException
*/
private PrincipalExpression transformBody(
Principal issuer,
CredentialDomain credDomain,
Element ele)
throws CredException, DomainSpecException
{
String tag = ele.getTagName();
RTUtil.debugInfo("parseBody() tag = " + tag);
PrincipalExpression prinExp = null;
if (tag.startsWith(PRINCIPAL))
{
prinExp =
transformPrincipalValue(ele, credDomain).getValue();
}
else if (tag.equals(ROLE_TERM))
{
RoleTerm roleTerm = transformRoleTerm(ele, credDomain);
prinExp = new Role(issuer, roleTerm);
}
else if (tag.equals(EXTERNAL_ROLE))
{
prinExp = transformExternalRole(ele, credDomain);
}
else if (tag.equals(LINKED_ROLE))
{
NodeList nodes = ele.getElementsByTagName(ROLE_TERM);
if (nodes.getLength() != 2)
throw new DomainSpecException(
improper_sub_element_for + "'LinkedRole'");
Element roleTermEle1 = (Element) nodes.item(0);
Element roleTermEle2 = (Element) nodes.item(1);
prinExp =
new LinkedRole(
transformRoleTerm(roleTermEle1, credDomain),
transformRoleTerm(roleTermEle2, credDomain));
}
else if (tag.equals(INTERSECTION))
{
prinExp = transformRoleIntersection(ele, credDomain);
}
else if (tag.equals(PRODUCT))
{
// TODO
throw new UnsupportedOperationException(
no_support_for + "'Product'");
}
else if (tag.equals(EXCLUSIVE_PRODUCT))
{
// TODO
throw new UnsupportedOperationException(
no_support_for + "'ExclusiveProduct");
}
return prinExp;
}
/**
* Method transformDelegation.
Returns a DelegationRole object for the body of a role definition
by parsing element:
<SimpleDelegation> ... </SimpleDelegation> Or <AdvancedDelegation> ... </AdvancedDelegation>* @param issuer * @param credDomain * @param delegationElement * @param controlElement * @return DelegationRole * @throws DomainSpecException * @throws CredException */ private DelegationRole transformDelegation( Principal issuer, CredentialDomain credDomain, Element delegationElement, Element controlElement) throws DomainSpecException, CredException { if (!delegationElement.getTagName().equals(DELEGATE_TO)) throw new DomainSpecException("Not a delegateTo element"); if (controlElement != null && !controlElement.getTagName().equals(CONTROL)) throw new DomainSpecException("Not a Control element"); PrincipalExpression delegateTo = null; Role control = null; // delegateTo Element[] elements = getChildElements(delegationElement); for (int i = 0; i < elements.length; i++) { Element child = elements[i]; String childName = child.getTagName(); if (childName.startsWith(PRINCIPAL)) { delegateTo = transformPrincipalValue(child, credDomain) .getValue(); } else if (childName.equals(ROLE_TERM)) { RoleTerm roleTerm = transformRoleTerm(child, credDomain); delegateTo = new Role(issuer, roleTerm); } else { throw new DomainSpecException( improper_sub_element_for + "'DelegatTo'"); } } // control if (controlElement != null) { elements = getChildElements(controlElement); for (int i = 0; i < elements.length; i++) { Element child = elements[i]; String childName = child.getTagName(); if (childName.equals(ROLE_TERM)) { RoleTerm roleTerm = transformRoleTerm(child, credDomain); control = new Role(issuer, roleTerm); } else if (childName.equals(EXTERNAL_ROLE)) { control = transformExternalRole(child, credDomain); } else { throw new DomainSpecException( improper_sub_element_for + "'Control'"); } } } return new DelegationRole(delegateTo, control); } /** * Method transformExternalRole.
<ExternalRole> ... </ExternalRole>* @param ele * @param credDomain * @return Role * @throws CredException * @throws DomainSpecException */ private Role transformExternalRole( Element ele, CredentialDomain credDomain) throws CredException, DomainSpecException { if (!ele.getTagName().equals(EXTERNAL_ROLE)) throw new DomainSpecException("Not an ExternalRole element."); Element[] elements = getChildElements(ele); if (elements.length != 2) throw new DomainSpecException( improper_sub_element_for + "'ExternalRole'"); Element prinEle = elements[0]; Element roleTermEle = elements[1]; return new Role( transformPrincipalValue(prinEle, credDomain).getValue(), transformRoleTerm(roleTermEle, credDomain)); } /** * Method transformRoleIntersection.
<Intersection> ... </Intersection>* @param ele * @param credDomain * @return RoleIntersection * @throws CredException * @throws DomainSpecException */ private RoleIntersection transformRoleIntersection( Element ele, CredentialDomain credDomain) throws CredException, DomainSpecException { if (!ele.getTagName().equals(INTERSECTION)) throw new DomainSpecException("Not an Intersection element."); RoleIntersection ri = new RoleIntersection(); Element[] elements = getChildElements(ele); int n = elements.length; for (int i = 0; i < n; i++) { Element child = elements[i]; String childTag = child.getTagName(); if (childTag.equals(ROLE_TERM)) { ri.and(transformRoleTerm(child, credDomain)); } else if (childTag.equals(EXTERNAL_ROLE)) { ri.and(transformExternalRole(child, credDomain)); } else { throw new DomainSpecException( improper_sub_element_for + "'Intersection'"); } } return ri; } /** * Method transformRoleTerm.
<RoleTerm> ... </RoleTerm>* @param ele * @param credDomain * @return RoleTerm * @throws CredException * @throws DomainSpecException */ private RoleTerm transformRoleTerm( Element ele, CredentialDomain credDomain) throws CredException, DomainSpecException { if (!ele.getTagName().equals(HEAD_ROLE_TERM) && !ele.getTagName().equals(ROLE_TERM)) throw new DomainSpecException("Not a RoleTerm element."); String roleName = ele.getAttribute(NAME); if (roleName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); String domain = ele.getAttribute(DOMAIN); RTUtil.debugInfo("**** roleName = " + roleName); RTUtil.debugInfo("**** domain = " + domain); RoleDeclaration roleDecl = credDomain.lookupRoleDeclaration(domain, roleName); RoleTerm roleTerm = new RoleTerm(roleDecl); NodeList children = ele.getElementsByTagName(PARAMETER); int n = children.getLength(); for (int i = 0; i < n; i++) { StringBuffer prefix = new StringBuffer(roleName); Element paramEle = (Element) children.item(i); String paramName = paramEle.getAttribute(NAME); //prefix.append(COLON).append(paramName); transformParameter( paramEle, prefix, roleTerm, credDomain); } return roleTerm; } /** * Method transformParameter.
<Parameter name="aa" id="s"> ... </Parameter>* @param ele * @param prefix * @param roleTerm * @param credDomain * @throws DomainSpecException */ //ValueSet private void transformParameter( Element ele, StringBuffer prefix, RoleTerm roleTerm, CredentialDomain credDomain) throws DomainSpecException { if (!ele.getTagName().equals(PARAMETER)) throw new DomainSpecException("Not a Parameter element."); String parameterName = ele.getAttribute(NAME); if (parameterName.length() == 0) throw new DomainSpecException( missing_attr_value + "'name'"); prefix.append(COLON).append(parameterName); DataType paramType = roleTerm.getParameterType(parameterName); String id = ele.getAttribute(ID); RTUtil.debugInfo("transformParameter() id = " + id); Element[] elements = getChildElements(ele); if (elements.length > 1) throw new DomainSpecException( improper_sub_element_for + "'Parameter'"); if (elements.length == 0) { // TODO: Create a null parameter value in this case. // It is related to Equals Element. ValueSet nullParameterValue = new ValueSet(paramType); roleTerm.putParameterValue( prefix.toString(), nullParameterValue); } else { Element valueEle = elements[0]; String tag = valueEle.getTagName(); if (tag.equals(EQUALS)) { // TODO throw new UnsupportedOperationException( no_support_for + "'Equals'"); } else if (tag.equals(SPECIAL_PRINCIPAL)) { // TODO throw new UnsupportedOperationException( no_support_for + "'SpecialPrincipal'"); } // the rest of the elements go to ValueSet else { transformValueSetGroup( paramType, valueEle, prefix, roleTerm, credDomain); } } } /** * Method transformValueSetGroup.
<Interval includeMin="true" includeMax="true"> <min> ... </min> <max> ... </max> </Interval>* @param type * @param ele * @return IntervalValueSet * @throws DomainSpecException */ private IntervalValueSet transformIntervalValue( OrderedType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(INTERVAL)) throw new DomainSpecException("Not an Interval element"); Element fromEle = getFirstChildElementByTagName(ele, FROM); Element toEle = getFirstChildElementByTagName(ele, TO); Element e1 = null, e2 = null; if (fromEle != null) e1 = getFirstChildElement(fromEle); if (toEle != null) e2 = getFirstChildElement(toEle); if (e1 != null && e2 != null) { if (!e1.getTagName().equals(e2.getTagName())) throw new DomainSpecException( improper_sub_element_for + "'Interval'"); } DataValue min = null, max = null; if (e1 != null) min = transformOrderedValue(type, e1); if (e2 != null) max = transformOrderedValue(type, e2); return new IntervalValueSet(type, min, max); } /** * Method transformOrderedValue.
<IntegerValue> ... </IntegerValue> or <DecimalValue> ... </DecimalValue> or <StirngValue> ... </StringValue> or <EnumValue> ... </EnumValue> or <TimeValue> ... </timeValue>* @param type * @param ele * @return DataValue * @throws DomainSpecException */ private DataValue transformOrderedValue( OrderedType type, Element ele) throws DomainSpecException { DataValue value = null; String tag = ele.getTagName(); if (tag.equals(INTEGER_VALUE)) { value = transformIntegerValue((IntegerType) type, ele); } if (tag.equals(DECIMAL_VALUE)) { value = transformDecimalValue((DecimalType) type, ele); } if (tag.equals(STRING_VALUE)) { value = transformStringValue((StringType) type, ele); } if (tag.equals(ENUM_VALUE)) { value = transformEnumValue((EnumType) type, ele); } if (tag.equals(TIME_VALUE)) { //value = transformTimeValue((TimeType)type, ele); } return value; } /** * Method transformIntegerValue.
<IntegerValue> 123 </IntegerValue>* @param type * @param ele * @return IntegerValue * @throws DomainSpecException */ private IntegerValue transformIntegerValue( IntegerType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(INTEGER_VALUE)) throw new DomainSpecException("Not an IntegerValue element."); Node textNode = ele.getFirstChild(); if (textNode.getNodeType() != org.w3c.dom.Node.TEXT_NODE) throw new DomainSpecException("Wrong elements for StringValue"); IntegerValue value = new IntegerValue(textNode.getNodeValue()); // Type checking. if (type != null && !type.isValidValue(value)) throw new DomainSpecException( illegal_value_for + "IntegerType :" + type.getName()); return value; } /** * Method transformDecimalValue.
<DecimalValue> 123 </DecimalValue>* @param type * @param ele * @return DecimalValue * @throws DomainSpecException */ private DecimalValue transformDecimalValue( DecimalType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(DECIMAL_VALUE)) throw new DomainSpecException("Wrong element"); Node textNode = ele.getFirstChild(); if (textNode.getNodeType() != org.w3c.dom.Node.TEXT_NODE) throw new DomainSpecException("Wrong elements for StringValue"); DecimalValue value = new DecimalValue(textNode.getNodeValue()); // Type checking. if (type != null && !type.isValidValue(value)) throw new DomainSpecException( illegal_value_for + "DecimalType :" + type.getName()); return value; } /** * Method transformStringValue.
<StringValue> 123 </StringValue>* @param type * @param ele * @return StringValue * @throws DomainSpecException */ private StringValue transformStringValue( StringType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(STRING_VALUE)) throw new DomainSpecException("Not a StringValue element"); Node textNode = ele.getFirstChild(); if (textNode.getNodeType() != org.w3c.dom.Node.TEXT_NODE) throw new DomainSpecException( improper_sub_element_for + "'StringValue'"); StringValue value = new StringValue(textNode.getNodeValue()); // Type checking. if (type != null && !type.isValidValue(value)) throw new DomainSpecException( illegal_value_for + "StringType :" + type.getName()); return value; } /** * Method transformEnumValue.
<EnumValue> 123 </EnumValue>* @param type * @param ele * @return EnumValue * @throws DomainSpecException */ private EnumValue transformEnumValue(EnumType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(ENUM_VALUE)) throw new DomainSpecException("Not an EnumValue element"); Node textNode = ele.getFirstChild(); if (textNode.getNodeType() != org.w3c.dom.Node.TEXT_NODE) throw new DomainSpecException( improper_sub_element_for + "'EnumValue'"); EnumValue value = new EnumValue(textNode.getNodeValue()); // Type checking. if (type != null && !type.isValidValue(value)) { RTUtil.debugInfo( "transformEnumValue() type name = " + type.getName()); RTUtil.debugInfo( "transformEnumValue() value = " + value.toString()); throw new DomainSpecException( illegal_value_for + "EnumType :" + type.getName()); } return value; } /** * Method transformTreeValue.
<TreeValue includeCurrent="true" includeChildren="true" includeDescendents="false"> cs.stanford.edu </TreeValue>* @param type * @param ele * @return TreeValueSet * @throws DomainSpecException */ private TreeValueSet transformTreeValue( TreeType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(TREE_VALUE)) throw new DomainSpecException("Not a TreeValue element"); Node textNode = ele.getFirstChild(); if (textNode.getNodeType() != org.w3c.dom.Node.TEXT_NODE) throw new DomainSpecException( improper_sub_element_for + "'TreeValue'"); boolean includeCurrent = RTUtil.parseBoolean( ele.getAttribute(INCLUDE_CURRENT), true); boolean includeChildren = RTUtil.parseBoolean( ele.getAttribute(INCLUDE_CHILDREN), false); boolean includeDescendents = RTUtil.parseBoolean( ele.getAttribute(INCLUDE_DESCENDENTS), false); String value = textNode.getNodeValue(); String separator = type.getSeparator(); StringTokenizer st = new StringTokenizer(value, separator); int size = st.countTokens(); ArrayList values = new ArrayList(size); while (st.hasMoreTokens()) { values.add((String) st.nextToken()); } TreeValue res = new TreeValue(type, values); // Type checking. if (type != null && !type.isValidValue(res)) throw new DomainSpecException( illegal_value_for + "TreeType :" + type.getName()); return new TreeValueSet( (TreeType) type, res, includeCurrent, includeChildren, includeDescendents); } /** * Method transformTimeValue.
<TimeValue> 2002-08-29T09:31:32 </TimeValue>* @param type * @param ele * @return TimeValue * @throws DomainSpecException */ private TimeValue transformTimeValue(TimeType type, Element ele) throws DomainSpecException { if (!ele.getTagName().equals(TIME_VALUE)) throw new DomainSpecException("Not a TimeValue element"); Node textNode = ele.getFirstChild(); if (textNode.getNodeType() != org.w3c.dom.Node.TEXT_NODE) throw new DomainSpecException( improper_sub_element_for + "'TimeValue'"); String dateString = textNode.getNodeValue(); String typeName = type.getName(); TimeValue value = new TimeValue( typeName, transformDateTime(typeName, dateString)); return value; } /** * Method transformDateTime.