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;
}
}