/************************************************
* Columbia University CS Department
* Network Security Lab
*
* Open and Survivable Embedded Systems (OASES)
*
* Structured Policy Command Language (SPCL)
*
*
* This software is provided as is without any
* warranty or guarantee of merchantibility
* or fitness for a particular purpose. This
* software is released under the terms of the
* GNU General Public License (GPL).
*
* Last updated: March 25, 2003
*
***********************************************/

package spcl.data;

import java.util.*;


/** 
 * The high-level container for a collection of
 * policies.
 *
 * The following is a discussion of the naming
 * scheme for zones, policies, principals, rules,
 * systemobjects, and groups.
 *
 * The general naming scheme is:
 *  rule:zone.policy.group.principal.rulenum
 *
 * thus, 'foo.bar.michael.michael.1' would refer to
 * the first Rule defined in Principal 'michael' in
 * Group 'michael' (each Principal gets its own Group
 * implicitly) in Policy 'bar' under Zone 'foo'.
 *
 * group:zone.policy.group
 * principal:zone.policy.group.principal
 * zone:zone
 * policy:zone.policy
 * action:zone.policy.object.action
 * object:zone.policy.object
 *
 * @author locasto@cs.columbia.edu
 *
*/
public class Zone{


  private String name = "";
  private Hashtable policies = new Hashtable();
  private Hashtable principals = new Hashtable();
  private Hashtable groups = new Hashtable();
  private Hashtable rules = new Hashtable();

  private int numPolicies=0;

  public Zone( String name ){
    this.name = name;
  }
  
  public String getName(){
    return name;
  }

  /** return the first policy in your hash */
  public Policy getFirst(){
    return ((Policy)(policies.elements().nextElement()));
  }

  /** 
   * Import the supplied policy into this zone.
   *
   * @param Policy p - the candidate policy
   * @throws PolicyException - if the call to <code>resolve()</code>
   *   fails in any way
   *
  */
  public void attach( Policy p ) throws PolicyException{

    resolve( p );

    //we are here only if resolve() returned peacefully
    policies.put( p.getName(), p );
    numPolicies++;

  }

  public int getNumPolicies(){
    return numPolicies;
  }

  public boolean isEmpty(){
    return (numPolicies<=0);
  }

  public Enumeration getPolicies(){
  	return policies.elements();
  }

  public Policy getPolicy( String policyName ){
    return ((Policy)policies.get( policyName ));
  }

  /** This method goes through the list of installed policies
   *  and determines if there are any conflicts. This method
   *  is automagically invoked during a call to <code>attach()</code>.
   * <p>
   *  The primary purpose of this method is to update the zone's 
   *  data structures of principals, rules, system objects, and groups. 
   *  The method will examine zones data structures and associate any
   *  new information with the appropriate object and create new objects
   *  as needed. 
   * <p>
   *  Note that the data structures in the Zone are the master ones. The
   *  data structures in the installed Policies are simply deltas. The
   *  only valid 'master' information that a Policy contains is information
   *  regarding its name and other meta-data.
   */
  private void resolve( Policy p ) throws PolicyException{
     if(null==p) 
       throw new PolicyException( "resolve() given null policy", 
                                  PolicyException.NULL_POLICY );

     return;
  }

  public boolean remove( String policyName ){

	//lock data
	//attempt removal
	//test for inconsistent state
	//if bad, rollback
	//else
	policies.remove( policyName );
	numPolicies--;
	//and trigger cascades (update zone data structures
	//with reduced capabilities of removed objects,princpals,etc)
	//unlock data

    return true;
  }
  

}
