package edu.stanford.rt.credential; import java.util.*; import edu.stanford.rt.util.*; import edu.stanford.rt.datatype.*; /** * @author Ninghui Li, Sandra Qiu
* * All the information about a declared role. In RTML, this is * represented by a RoleDeclaration element in a * ApplicationDomainSpecification document. * * Issue: Do not support identity yet. */ public class RoleDeclaration implements Constants, java.io.Serializable { /** * Issuer traces types */ static public HashMap issuerTracesTypes; /** * Subject traces types */ static public HashMap subjectTracesTypes; static { issuerTracesTypes = new HashMap(4); issuerTracesTypes.put("all", new Integer(ISSUER_TRACES_ALL)); issuerTracesTypes.put("def", new Integer(ISSUER_TRACES_DEF)); issuerTracesTypes.put( "rule", new Integer(ISSUER_TRACES_RULE)); issuerTracesTypes.put( "none", new Integer(ISSUER_TRACES_NONE)); subjectTracesTypes = new HashMap(3); subjectTracesTypes.put( "all", new Integer(SUBJECT_TRACES_ALL)); subjectTracesTypes.put( "fact", new Integer(SUBJECT_TRACES_FACT)); subjectTracesTypes.put( "none", new Integer(SUBJECT_TRACES_NONE)); } /** * Default issuer traces type: rule */ static public int DEFAULT_ISSUER_TYPE = ISSUER_TRACES_RULE; /** * Defualt issuer traces type: fact. */ static public int DEFAULT_SUBJECT_TYPE = SUBJECT_TRACES_FACT; /** * Role declaration context. *
* The DomainSpecification in which the current role * is declared. */ private DomainSpecification context; /** Role name.
* In RTML: attribute name. */ private String name; /** Default is DEFAULT_ISSUER_TYPE
* In RTML: attribute issuerTracesType. */ private int issuerTracesType = DEFAULT_ISSUER_TYPE; /** Default is DEFAULT_SUBJECT_TYPE
* In RTML: attribute subjectTracesType. */ private int subjectTracesType = DEFAULT_SUBJECT_TYPE; /** Default is 1
* In RTML: attribute dimension. */ private int dimension = 1; /** Default is false.
* In RTML: attribute isIdentity. */ private boolean isIdentity = false; /** Maps String (parameter name) to DataType (parameter type). */ private OrderedMap parameterDeclarations; /** Declaration type: Restriction, Extension, Projection or Plain. */ private int declarationType; /** BaseRole Element for Restriction, Extension, Projection. */ private RoleDeclaration baseRole; /** This map keeps track of the ordersing of the flattend name-prefixes. A name-prefix is colon-separated name concatenation.*/ private HashMap prefixToPositions; private HashMap positionToPrefixes; // Role declaration types static private final int RESTRICTION = 1; static private final int EXTENSION = 2; static private final int PROJECTION = 3; static private final int PLAIN = 4; /** * Private contructor ensures that no one else can contruct a RoleDeclaration * object and the state of a RoleDeclaration object is complete (unmodifiable) * once it is created.
* And the newly created RoleDeclaration's parameter-postion mapping is also * calculated. * @param context * @param name * @param issuerTracesType * @param subjectTracesType * @param dimension * @param isIdentity * @param declarationType * @param baseRole * @param parameterDeclarations * @throws DomainSpecException */ private RoleDeclaration( DomainSpecification context, String name, int issuerTracesType, int subjectTracesType, int dimension, boolean isIdentity, int declarationType, RoleDeclaration baseRole, OrderedMap parameterDeclarations) throws DomainSpecException { this.context = context; this.name = name; this.issuerTracesType = issuerTracesType; this.subjectTracesType = subjectTracesType; this.dimension = dimension; this.isIdentity = isIdentity; this.declarationType = declarationType; this.baseRole = baseRole; this.parameterDeclarations = parameterDeclarations; this.parameterDeclarations.setUneditable(); this.prefixToPositions = new HashMap(); this.positionToPrefixes = new HashMap(); // Compute parameters, which includes all parameters of base role plus // those in "this" role. calculatePrefixPositions( new StringBuffer(name), 0, this.parameterDeclarations, this.prefixToPositions, this.positionToPrefixes); } /** * Method createRestrictionRole. * Public interface to construct a Restriction type * RoleDeclaration object. * @param name * @param isIdentity * @param baseRole * @param newParameters * @return RoleDeclaration * @throws DomainSpecException */ public static RoleDeclaration createRestrictionRole( DomainSpecification context, String name, boolean isIdentity, RoleDeclaration baseRole, OrderedMap newParameters) throws DomainSpecException { if (baseRole == null) throw new DomainSpecException(""); int issuerTracesType = baseRole.getIssuerTracesType(); int subjectTracesType = baseRole.getSubjectTracesType(); int dimension = baseRole.getDimension(); OrderedMap parameterDeclarations = new OrderedMap(String.class, DataType.class); parameterDeclarations.putAll( baseRole.getParameterDeclarations()); parameterDeclarations.putAll(parameterDeclarations); return new RoleDeclaration( context, name, issuerTracesType, subjectTracesType, dimension, isIdentity, RESTRICTION, baseRole, parameterDeclarations); } /** * Method createExtensionRole. * Public interface to construct an Extension type * RoleDeclaration object. * @param name * @param isIdentity * @param baseRole * @param newParameters * @return RoleDeclaration * @throws DomainSpecException */ public static RoleDeclaration createExtensionRole( DomainSpecification context, String name, boolean isIdentity, RoleDeclaration baseRole, OrderedMap newParameters) throws DomainSpecException { if (baseRole == null) throw new DomainSpecException(""); int issuerTracesType = baseRole.getIssuerTracesType(); int subjectTracesType = baseRole.getSubjectTracesType(); int dimension = baseRole.getDimension(); OrderedMap parameterDeclarations = new OrderedMap(String.class, DataType.class); parameterDeclarations.putAll( baseRole.getParameterDeclarations()); parameterDeclarations.putAll(parameterDeclarations); return new RoleDeclaration( context, name, issuerTracesType, subjectTracesType, dimension, isIdentity, EXTENSION, baseRole, parameterDeclarations); } /** * Method createProjectionRole. * Public interface to construct a Projection type * RoleDeclaration object. * @param name * @param isIdentity * @param baseRole * @param parameterNames * @return RoleDeclaration * @throws DomainSpecException */ public static RoleDeclaration createProjectionRole( DomainSpecification context, String name, boolean isIdentity, RoleDeclaration baseRole, String[] parameterNames) throws DomainSpecException { if (baseRole == null) throw new DomainSpecException(""); int issuerTracesType = baseRole.getIssuerTracesType(); int subjectTracesType = baseRole.getSubjectTracesType(); int dimension = baseRole.getDimension(); OrderedMap parameterDeclarations = new OrderedMap(String.class, DataType.class); OrderedMap baseRoleParameters = baseRole.getParameterDeclarations(); for (int i = 0; i < parameterNames.length; i++) { DataType type = baseRole.getParameterType(parameterNames[i]); parameterDeclarations.put(parameterNames[i], type); } return new RoleDeclaration( context, name, issuerTracesType, subjectTracesType, dimension, isIdentity, PROJECTION, baseRole, parameterDeclarations); } /** * Method createPlainRole. * Public interface to construct a Plain type of * RoleDeclaration object. Identity is not supported. * @param name * @param issuerTracesType * @param subjectTracesType * @param dimension * @param isIdentity * @param newParameters * @return RoleDeclaration * @throws DomainSpecException */ public static RoleDeclaration createPlainRole( DomainSpecification context, String name, int issuerTracesType, int subjectTracesType, int dimension, boolean isIdentity, OrderedMap newParameters) throws DomainSpecException { return new RoleDeclaration( context, name, issuerTracesType, subjectTracesType, dimension, isIdentity, PLAIN, null, newParameters); } /** Returns the role declaration context. */ public DomainSpecification getContext() { return context; } /** Returns the role name. */ public String getName() { return name; } /** Returns the value for issuerTracesType. */ public int getIssuerTracesType() { return issuerTracesType; } /** Returns the value for subjectTracesType. */ public int getSubjectTracesType() { return subjectTracesType; } /** * Returns the value for dimension. */ public int getDimension() { return dimension; } /** Returns the base role object. */ public RoleDeclaration getBaseRole() { return baseRole; } /** Checks whether this role is an identity-based role. */ public boolean isIdentity() { return isIdentity; } /** * Method getParameterDeclarations. * @return OrderedMap * Returns an OrderedMap of parameter declarations in * this role declaration object.
* For Restriction or Extension type RoleDeclaration, * the map contains parameters declared both in base role and this role. * For Projection type RoleDeclaration, * the map contains only those paraeters declared in base role with * matching names with this role's declared parameters. * * @throws DomainSpecException */ public synchronized OrderedMap getParameterDeclarations() throws DomainSpecException { if (parameterDeclarations.isEditable()) throw new IllegalStateException("Parameter declarations are not finalized."); return parameterDeclarations; } /** * Method getParameterType. * @param paramName name of the declared parameter. * @return DataType type of the declared parameter. * @throws DomainSpecException */ public DataType getParameterType(String paramName) throws DomainSpecException { return (DataType) parameterDeclarations.get(paramName); } /** Returns a unmodifiable view of prefix-to-position map.*/ public synchronized Map getPrefixToPositions() { return Collections.unmodifiableMap(prefixToPositions); } /** Returns a unmodifiable view of position-to-prefix map.*/ public synchronized Map getPositionToPrefixes() { return Collections.unmodifiableMap(positionToPrefixes); } /** Returns the total number of the prefixes in the map.*/ public int getTotalPrefixes() { return prefixToPositions.size(); } /** * Method getPosition. * @param prefix * the prefix to get the position with. * @return int * the postition of the given prefix. */ public int getPosition(String prefix) { Integer pos = (Integer) prefixToPositions.get(prefix); return pos.intValue(); } /** * Method getPrefix. * @param position * the position to get prefix with. * @return String * the prefix at the given position. */ public String getPrefix(int position) { return (String) positionToPrefixes.get(new Integer(position)); } /** * Method toString. * @param indent * @return String */ public String toString(String indent) { String thisIndent = indent + " "; StringBuffer sb = new StringBuffer(); sb.append(thisIndent).append("RoleDeclaration: ").append( name).append( "\n"); sb .append(thisIndent + " ") .append("issuerTracesType = ") .append(getIssuerTracesTypeString(issuerTracesType)) .append("\n"); sb .append(thisIndent + " ") .append("subjectTracesType = ") .append(getSubjectTracesTypeString(subjectTracesType)) .append("\n"); sb.append(thisIndent + " ").append("Parameters: \n"); Iterator it = parameterDeclarations.keyIterator(); while (it.hasNext()) { String key = (String) it.next(); sb.append(thisIndent + " ").append(key); try { DataType value = (DataType) parameterDeclarations.get(key); sb.append(" ").append(value.getName()).append( "\n"); } catch (DomainSpecException e) { e.printStackTrace(); } } return sb.toString(); } /** * Method calculatePrefixPositions. * @param prefix * current prefix. Prefix is a lolon-saparated string, which * is the concatenation of role name and parameter names. * @param position * the current position of the prefix. * @param paramDeclarations * all parameters declared in this role. * @param prefixToPositionMap * a HashMap which maps a prefix to its position. * @param positionToPrefixMap * a HashMap which maps a position to its prefix * @throws DomainSpecException * */ private synchronized void calculatePrefixPositions( StringBuffer prefix, int position, OrderedMap paramDeclarations, HashMap prefixToPositionMap, HashMap positionToPrefixMap) throws DomainSpecException { RTUtil.debugInfo( "RoleDeclaration.calculatePrefixPositions(, , , , ) ...."); // RTUtil.debugInfo("prefix = " + prefix); Iterator paramNameIt = paramDeclarations.keyIterator(); StringBuffer newPrefix = new StringBuffer(prefix.toString()); while (paramNameIt.hasNext()) { newPrefix.append(COLON); String paramName = (String) paramNameIt.next(); newPrefix.append(paramName); RTUtil.debugInfo("newPrefix = " + newPrefix.toString()); DataType paramType = getParameterType(paramName); if (paramType instanceof RecordType) { OrderedMap fieldDeclarations = ((RecordType) paramType).getFieldDeclarations(); calculatePrefixPositions( newPrefix, position++, fieldDeclarations, prefixToPositionMap, positionToPrefixMap); position++; } else { position++; RTUtil.debugInfo("position = " + position); prefixToPositionMap.put( newPrefix.toString(), new Integer(position)); positionToPrefixMap.put( new Integer(position), newPrefix.toString()); } //RTUtil.debugInfo("**** prefix = " + prefix.toString()); newPrefix = new StringBuffer(prefix.toString()); //RTUtil.debugInfo("newPrefix 2 = " + newPrefix.toString()); } } private String getIssuerTracesTypeString(int issuerTracesType) { String res = null; switch (issuerTracesType) { case ISSUER_TRACES_ALL : res = "all"; break; case ISSUER_TRACES_DEF : res = "def"; break; case ISSUER_TRACES_RULE : res = "rule"; break; case ISSUER_TRACES_NONE : res = "none"; break; default : res = "rule"; break; } return res; } private String getSubjectTracesTypeString(int subjectTracesType) { String res = null; switch (subjectTracesType) { case SUBJECT_TRACES_ALL : res = "all"; break; case SUBJECT_TRACES_FACT : res = "fact"; break; case SUBJECT_TRACES_NONE : res = "none"; break; default : res = "fact"; break; } return res; } }