Index: fedd/abac-src/rtml/src/edu/stanford/rt/credential/CredentialDomain.java
===================================================================
--- fedd/abac-src/rtml/src/edu/stanford/rt/credential/CredentialDomain.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rtml/src/edu/stanford/rt/credential/CredentialDomain.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,321 @@
+package edu.stanford.rt.credential;
+
+import java.util.*;
+
+import org.w3c.dom.Element;
+
+import edu.stanford.rt.datatype.*;
+import edu.stanford.rt.util.*;
+
+/**
+ * @author Ninghui Li, Sandra Qiu<br>
+ *
+ * Implementation of <code>Credential</code> element.  Only one CredentialDomain object is associated with each Credential 
+ * object.
+*/
+public class CredentialDomain extends DomainSpecification
+{
+	/**
+	 * Issuer of the associated Credential.
+	 */
+	private Principal issuer;
+
+	/** 
+	 * validity time of the associated Credential.
+	 */
+	private ValidityTime validityTime;
+
+	/**
+	 *  maps String (principal shortName) to Principal object
+	 */
+	private HashMap principals;
+
+    /**
+     *  reverse lookup of Principal instances in this CredentialDomain
+     */
+    private HashMap shortNames;
+
+	/**
+	 * list of role defined in this credential.
+	 */
+	private ArrayList roleDefinitions;
+
+	/**
+	 * the XML Element of the associated Credential.
+	 */
+	private Element credentialElement;
+
+	/**
+	 * Constructor for CredentialDomain.
+	 */
+	public CredentialDomain(
+		Element credentialElement,
+		RTContext rtContext)
+		throws DomainSpecException
+	{
+		super(rtContext);
+		this.credentialElement = credentialElement;
+		this.principals = new HashMap();
+        this.shortNames = new HashMap();
+		this.roleDefinitions = new ArrayList();
+	}
+
+	/**
+	 * Method addPrincipal.
+	 * @param shortName
+	 * @param principal
+	 * @throws DomainSpecException
+	 */
+	public void addPrincipal(String shortName, Principal principal)
+		throws DomainSpecException
+	{
+		RTUtil.debugInfo("addPrincipal() shortName = " + shortName);
+		if (principals.get(shortName) != null)
+			throw new DomainSpecException(
+				"Duplicated principal entries for shortName '"
+					+ shortName
+					+ "'");
+		principals.put(shortName, principal);
+        shortNames.put(principal, shortName);
+	}
+
+	/**
+	 * Method getPrincipal.
+	 * @param shortName
+	 * @return Principal
+	 *  returns null if cannot find one.
+	 */
+	public Principal getPrincipal(String shortName)
+	{
+		return (Principal) principals.get(shortName);
+	}
+
+    /**
+     * Method getPrincipal.
+     * @param principal An instance of a principal object, currently a hash
+     * @return the short name id used for human readable formatting
+     *  returns <CODE>null</CODE> if cannot find one.
+     */
+    public String getPrincipal(Principal principal) {
+        return (String)shortNames.get(principal);
+    }
+
+	/**
+	 * Method setIssuer.
+	 * @param issuer
+	 */
+	public void setIssuer(Principal issuer)
+	{
+		this.issuer = issuer;
+	}
+	/**
+	 * Returns the issuer.
+	 * @return Principal
+	 */
+	public Principal getIssuer()
+	{
+		return issuer;
+	}
+
+	/**
+	 * Returns the validityTime.
+	 * @return ValidityTime
+	 */
+	public ValidityTime getValidityTime()
+	{
+		return validityTime;
+	}
+	/**
+	 * Method setValidityTime.
+	 * @param validityTime
+	 */
+	public void setValidityTime(ValidityTime validityTime)
+	{
+		this.validityTime = validityTime;
+	}
+
+    /**
+     * accessor method for retrieving the underlying DOM object
+     */
+    public Element getCredentialElement() {
+        return credentialElement;
+    }
+
+	/**
+	 * Method toString.
+	 * @param indent
+	 * @return String
+	 */
+	public String toString(String indent)
+	{
+		String thisIndent = indent + "  ";
+		StringBuffer sb = new StringBuffer();
+
+		sb.append(thisIndent).append(
+			"CredentialDomain:   hashID = "
+				+ getHashID().toString()
+				+ "\n");
+		sb
+			.append(thisIndent + "  ")
+			.append("PrincipalType = ")
+			.append(getPrincipalType())
+			.append("\n");
+
+		sb.append(thisIndent + "  ").append("Imported Domains: \n");
+		try
+		{
+			Iterator it = getImportedDomains().keyIterator();
+			while (it.hasNext())
+			{
+				String key = (String) it.next();
+				ApplicationDomain value =
+					(ApplicationDomain) getImportedDomains().get(key);
+				sb.append(thisIndent + "    ").append(key).append(
+					"\n");
+				sb.append(thisIndent + "    ").append(
+					value.getUri()).append(
+					"\n");
+			}
+
+		}
+		catch (DomainSpecException e)
+		{
+			e.printStackTrace();
+		}
+
+		sb.append(thisIndent + "  ").append("Type Declarations: \n");
+		try
+		{
+			Iterator it = getTypeDeclarations().keyIterator();
+			while (it.hasNext())
+			{
+				String key = (String) it.next();
+				DataType value =
+					(DataType) getTypeDeclarations().get(key);
+				sb.append(thisIndent + "    ").append(key).append(
+					"\n");
+				sb.append(
+					value.toString(thisIndent + "    ")).append(
+					"\n");
+			}
+		}
+		catch (DomainSpecException e)
+		{
+			e.printStackTrace();
+		}
+
+		sb.append(thisIndent + "  ").append("Role Declarations: \n");
+		try
+		{
+			Iterator it = getRoleDeclarations().keyIterator();
+			while (it.hasNext())
+			{
+				String key = (String) it.next();
+				RoleDeclaration value =
+					(RoleDeclaration) getRoleDeclarations().get(key);
+				sb.append(thisIndent + "    ").append(key).append(
+					"\n");
+				sb.append(
+					value.toString(thisIndent + "    ")).append(
+					"\n");
+			}
+		}
+		catch (DomainSpecException e)
+		{
+			e.printStackTrace();
+		}
+		return sb.toString();
+	} // end of toString()
+
+	/* (non-Javadoc)
+	 * @see edu.stanford.rt.credential.DomainSpecification#setHashID(HashID)
+	 */
+	public void setHashID(HashID hashID) throws DomainSpecException
+	{
+		if (isComplete())
+			throw new DomainSpecException("CredentialDomain unmodifiable.");
+		if (hashID.getHashType() != HashID.CREDENTIAL_DOMAIN)
+			throw new DomainSpecException("Wrong type of hash id");
+		super.setHashID(hashID);
+	}
+
+	/**
+	 * Method roleDefinitionIterator.
+	 * @return Iterator
+	 */
+	public Iterator roleDefinitionIterator()
+	{
+		return roleDefinitions.iterator();
+	}
+
+	/**
+	 * Add a new role definition.
+	 * @param roleDefinition The roleDefinition to set
+	 */
+	public void addRoleDefinition(RoleDefinition roleDefinition)
+	{
+		this.roleDefinitions.add(roleDefinition);
+	}
+	/**
+	 * Method lookupType.
+	 *      Look up the DataType declaration by given typeName in the current domain.
+	 *  if cannot find one then look it up in system domain.
+	 * @param typeName
+	 * @return DataType
+	 * @throws DomainSpecException
+	 *      if cannot find a DataType declaration by the given name.
+	 */
+	public DataType lookupType(String typeName)
+		throws DomainSpecException
+	{
+		//RTUtil.debugInfo(" lookupType()>>>> isSystemDomain = " + isSystemDomain);
+		DataType type = super.lookupType(typeName);
+		if (type == null)
+		{
+			type =
+				getContext().getSystemDomain().lookupType(typeName);
+		}
+		if (type == null)
+		{
+			throw new DomainSpecException(
+				"Type '" + typeName + "' not found.");
+		}
+		return type;
+	}
+
+	/**
+	 * Method lookupRoleDeclaration.
+	 *      Look up the role declaration by given roleName in the current domain.
+	 *  If cannot find one then look it up in system domain.
+	 * @param roleName
+	 * @return RoleDeclaration
+	 * @throws DomainSpecException
+	 *      if cannot find one.
+	 */
+	public RoleDeclaration lookupRoleDeclaration(String roleName)
+		throws DomainSpecException
+	{
+		RTUtil.debugInfo(
+			"DomainSpecification(id="
+				+ ((getHashID() == null)
+					? "null"
+					: getHashID().toString())
+				+ ") looking up role '"
+				+ roleName
+				+ "'");
+
+		RoleDeclaration role = super.lookupRoleDeclaration(roleName);
+		if (role == null)
+		{
+			role =
+				getContext().getSystemDomain().lookupRoleDeclaration(
+					roleName);
+		}
+		if (role == null)
+		{
+			throw new DomainSpecException(
+				"Role '" + roleName + "' has not been declared.");
+		}
+		return role;
+	}
+}
