package edu.stanford.rt.credential; import java.util.*; import edu.stanford.rt.datatype.*; import edu.stanford.rt.credential.*; import edu.stanford.rt.util.*; /** * @author Ninghui Li, Sandra Qiu
* * This class stores the common information about an ApplicationDomain or * a CredentialDomain. The info includes the following: * principal type, imported application domains, type declarations, * role declarations, hash id, RTML context, and the parsing status. * */ public class DomainSpecification { /** * Principal type */ private SimpleType principalType; /** * Stores all imported domains in this domain, * mapping string (domain name) to ApplicationDomain object. */ private OrderedMap importedDomains; /** * Stores all type decalarations in this domain, * mapping string(type name) to type declaration object. */ private OrderedMap typeDeclarations; /** * Stores all role declarations in this domain, * mapping string(role name) to role declaration object. */ private OrderedMap roleDeclarations; /** * A flag indicates the parsing status of the domain. */ private boolean completeState; /** The hash value of the domain. */ private HashID hashID; /** * RTML Context */ private RTContext context; /** * Constuctor for DomainSpecification. Contructs a DomainSpecification object with the specific uri. Include System DomainSpecification for non-system DomainSpecification object. * @param uri * @param isSystemDomain * @param context * @throws DomainSpecException */ DomainSpecification(RTContext context) throws DomainSpecException { this.completeState = false; this.importedDomains = new OrderedMap(String.class, DomainSpecification.class); this.typeDeclarations = new OrderedMap(String.class, DataType.class); this.roleDeclarations = new OrderedMap(String.class, RoleDeclaration.class); this.context = context; } // /** // Copies over the type declarations and role declarations from the // included domain specification objects. // */ // private void includeDomain(DomainSpecification ds) // throws DomainSpecException // { // SimpleType prinType = ds.getPrincipalType(); // if (prinType != null) // { // if (this.principalType == null) // { // this.principalType = prinType; // } // else if (!prinType.equals(this.principalType)) // { // throw new DomainSpecException("Pincipal Type Conflict!"); // } // } // typeDeclarations.putAll(ds.getTypeDeclarations()); // roleDeclarations.putAll(ds.getRoleDeclarations()); // } /** * Method importDomain. * Add a newly imported domain map. * @param name * the short name to refer to spec with the domain. * @param spec * @throws DomainSpecException */ public synchronized void importDomain( String name, ApplicationDomain spec) throws DomainSpecException { importedDomains.put(name, spec); } /** * Method addType. * Add a new type declaration to the domain.
* @param type * @throws DomainSpecException * DomainSpecException when a duplicated type declaration, * i.e. a type declaration with the same name and same data * type, is added. */ public synchronized void addType(DataType type) throws DomainSpecException { String typeName = type.getName(); if (typeExistsInSystemDomain(typeName)) throw new DomainSpecException( "Type '" + typeName + "' already declared in system domain"); typeDeclarations.put(typeName, type); } /** * Method addType. * Add XML built-in type. * @param typeName * @throws DomainSpecException */ public synchronized void addType(String typeName) throws DomainSpecException { if (typeExistsInSystemDomain(typeName)) throw new DomainSpecException( "Type '" + typeName + "' already declared in system domain"); typeDeclarations.put(typeName, null); } /** * Method addRole. * Add a new role declaration to the domain. * @param role * @throws DomainSpecException */ public synchronized void addRole(RoleDeclaration role) throws DomainSpecException { RTUtil.debugInfo( "DomainSpecification(id=" + getHashID().toString() + ") adding role '" + role.getName() + "'"); String roleName = role.getName(); if (roleExistsInSystemDomain(roleName)) throw new DomainSpecException( "Role '" + roleName + "' already declared in system domain"); roleDeclarations.put(roleName, role); } /** * Method setPrincipalType. * @param prinType * @throws DomainSpecException */ public synchronized void setPrincipalType(SimpleType prinType) throws DomainSpecException { if (this.principalType == null) this.principalType = prinType; else if (!prinType.equals(this.principalType)) throw new DomainSpecException("Pincipal Type Conflict!"); } /** * Method isComplete. * checks whether the parsing is completed. * @return boolean */ public boolean isComplete() { return completeState; } /** * Method setComplete. * marks the parsing status as complete, so no modification * is allowed for imported domains, type declarations , and * role declarations maps. */ public synchronized void setComplete() { completeState = true; importedDomains.setUneditable(); typeDeclarations.setUneditable(); roleDeclarations.setUneditable(); } /** * Method lookupImportedDomain. * Lookup an imported domain by the given domainRef * in the currnt domain. * @param domainRef * @return DomainSpecification * @throws DomainSpecException * if cannot find one */ public DomainSpecification lookupImportedDomain(String domainRef) throws DomainSpecException { DomainSpecification spec = (DomainSpecification) importedDomains.get(domainRef); if (spec == null) { throw new DomainSpecException( "Domain '" + domainRef + "' not found."); } return spec; } /** * Method lookupType. * Look up the DataType declaration by given typeName * in the current domain. * @param typeName * @return DataType * returns null if cannot find one. * @throws DomainSpecException * if cannot find a DataType declaration by the given name. */ public DataType lookupType(String typeName) throws DomainSpecException { return (DataType) typeDeclarations.get(typeName); } /** * Method lookupType. * Look up the DataType declaration by given typeName in the given domain. * @param domainRef * specifies which domain to look up in. If domainRef is null or an * empty string, then look up in the current domain. * @param typeName * @return DataType * @throws DomainSpecException * if cannot find a DataType with given name. */ public DataType lookupType(String domainRef, String typeName) throws DomainSpecException { DataType type; if (domainRef == null || domainRef.length() == 0) { type = this.lookupType(typeName); } else { DomainSpecification importedSpec = this.lookupImportedDomain(domainRef); type = importedSpec.lookupType(typeName); } return type; } /** * Method lookupRoleDeclaration. * Look up the role declaration by given roleName in the current domain. * @param roleName * @return RoleDeclaration * returns null if cannot find one. * @throws DomainSpecException * if cannot find one. */ public RoleDeclaration lookupRoleDeclaration(String roleName) throws DomainSpecException { return (RoleDeclaration) roleDeclarations.get(roleName); } /** * Method lookupRoleDeclaration. * looks up a role declaration by given roleName in the given domain. * @param domainRef * specifies which domain to look up in. If domainRef is null or an * empty string, then look up in the current domain. * @param roleName * @return RoleDeclaration * @throws DomainSpecException * if cannot find a one. */ public RoleDeclaration lookupRoleDeclaration( String domainRef, String roleName) throws DomainSpecException { RoleDeclaration role; if (domainRef == null || domainRef.length() == 0) { role = this.lookupRoleDeclaration(roleName); } else { DomainSpecification importedSpec = this.lookupImportedDomain(domainRef); role = importedSpec.lookupRoleDeclaration(roleName); } return role; } /** * Method getContext. * @return RTContext */ public RTContext getContext() { return context; } /** * Method getTypeDeclarations. * @return OrderedMap * @throws DomainSpecException * when parsing is not completed. */ public OrderedMap getTypeDeclarations() throws DomainSpecException { if (!isComplete()) throw new DomainSpecException("Still parsing current domain specification"); return typeDeclarations; } /** * Method getRoleDeclarations. * @return OrderedMap * @throws DomainSpecException * when parsing is not completed. */ public OrderedMap getRoleDeclarations() throws DomainSpecException { if (!isComplete()) throw new DomainSpecException("Still parsing current domain specification"); return roleDeclarations; } /** * Method getImportedDomains. * @return OrderedMap * @throws DomainSpecException * when parsing is not completed. */ public OrderedMap getImportedDomains() throws DomainSpecException { if (!isComplete()) throw new DomainSpecException("Still parsing current domain specification"); return importedDomains; } /** * Method getPrincipalType. * @return SimpleType */ public SimpleType getPrincipalType() { return this.principalType; } /** * Returns the hashID. * @return ApplicationDomainHashID */ public HashID getHashID() { return this.hashID; } /** * Sets the hashID. * @param hashID The hashID to set */ public synchronized void setHashID(HashID hashID) throws DomainSpecException { this.hashID = hashID; } /** * Method typeExistsInSystemDomain. * checks whether a DataType with given typeName is already * declcared in system domain. * @param typeName * @return boolean */ private boolean typeExistsInSystemDomain(String typeName) { if (context == null) return false; try { DataType t = context.getSystemDomain().lookupType(typeName); return true; } catch (DomainSpecException e) { return false; } } /** * Method roleExistsInSystemDomain. * checks whether a RoleDeclaration with given roleName is already * declcared in system domain. * @param roleName * @return boolean */ private boolean roleExistsInSystemDomain(String roleName) { if (context == null) return false; try { RoleDeclaration r = context.getSystemDomain().lookupRoleDeclaration( roleName); return true; } catch (DomainSpecException e) { return false; } } }