/*
 * DomainArbitrator.java (Performs all the necessary action for
 *                        DomainSecurity)
 *
 * Written by : Nitin Jeevan Motgi (nmotgi@cs.ucf.edu)
 *
 * Portions copyright(c) 2001-2002 to School of Electrical Engineering
 * and Computer Science.
 *
 * All rights reserved.
*/

/* Import Java Libraries.*/
import java.lang.*;
import java.util.*;

/* Start of DomainArbitrator.*/
public class DomainArbitrator{
 /* Some Scratch Pad Variables.*/
 int ObjectSize = 0,DomainSize = 0,UserSize = 0;
 /* String Variables. 2-Dimensional String Arrays*/
 String[][] Domain,User,Action,DifDomain,DifUser;
 /* Single Dimension arrays.*/
 String[]   DifObject;
 /* Global Object. Uses staticaly created Objects from
    DomainSecurity Class.*/
 DomainSecurity DS = new DomainSecurity();

 /* gets one character from the buffer and flushes the system buffer.*/
 public static void getChar(){
  try{
   System.in.read();
   System.in.skip(System.in.available());
  }catch(Exception e){e.printStackTrace();}
 }/* End of getChar.*/

 /* Default Constrcutor called from DomainSecurity.*/
 public DomainArbitrator(String[][] Domain, String[][] User, String[][] Action){
  this.Domain = Domain;
  this.User = User;
  this.Action = Action;
  DifDomain = new String[1000][1000];
  DifUser = new String[1000][1000];
  DifObject = new String[1000];
 }/* Default Constructor.*/

 /* This is initialisation function called within this file, to set 
    all the necessary backup variables.*/
 private void Init(){
  /*Insert all the different objects into DifObject array*/
  for (int nIndexi = 0; nIndexi < DS.nDomainEntry; nIndexi++){
   boolean insert = false;
   /*If the object is found then ignore it*/
   for(int nIndexj = 0; nIndexj < ObjectSize; nIndexj++){
    if(Domain[nIndexi][1].compareTo(DifObject[nIndexj]) == 0){
     insert = true;
     break;
    }/* End if.*/
   }/* End for.*/

   /*Insert only if the object is not found*/
   if (insert == false){
    DifObject[ObjectSize] = Domain[nIndexi][1];
    ObjectSize++;
   }/* End if.*/
  }/*End for.*/

  /* Domain Information is secured.*/
  for (int nIndexi = 0; nIndexi < DS.nDomainEntry; nIndexi++){
   int enter = 0;
   boolean inserted = false;
   for(int nIndexj = 0; nIndexj < DomainSize; nIndexj++){
    if(Domain[nIndexi][0].compareTo(DifDomain[nIndexj][0]) == 0){
     enter = nIndexj;
     inserted = true;
     break;
    }/* End if.*/
   }/* End for.*/

   if (inserted == false){
    DifDomain[DomainSize][0] = Domain[nIndexi][0];
    enter = DomainSize;
    for(int nIndexh = 1; nIndexh <= ObjectSize; nIndexh++)
     DifDomain[enter][nIndexh] = " ";
    DomainSize++;
   }/* End if.*/

   /*It stores the the bPermission for the domain*/
   for(int nIndexk = 0; nIndexk < ObjectSize; nIndexk++){
    if(Domain[nIndexi][1].compareTo(DifObject[nIndexk]) == 0){
     DifDomain[enter][nIndexk+1] = Domain[nIndexi][2];
     break;
    }/* End if.*/
   }/* End for.*/
  }/*End for.*/

  for (int nIndexi = 0; nIndexi < DS.nUserEntry; nIndexi++){
   int enter = 0;
   boolean inserted = false;
   for(int nIndexj = 0; nIndexj < UserSize; nIndexj++){
    if(User[nIndexi][0].compareTo(DifUser[nIndexj][0]) == 0){
     enter = nIndexj;
     inserted = true;
     break;
    }/* End if.*/
   }/* End for.*/
   if (inserted == false){
    DifUser[UserSize][0] = User[nIndexi][0];
    enter = UserSize;
    for(int nIndexh = 1; nIndexh <= DomainSize; nIndexh++)
     DifUser[enter][nIndexh] = " ";
    UserSize++;
   }/* End if.*/

   for(int nIndexk = 0; nIndexk < DomainSize; nIndexk++){
    if(User[nIndexi][1].compareTo(DifDomain[nIndexk][0]) == 0){
      for(int nIndexm = 1; nIndexm <= DomainSize; nIndexm++){
       if(DifUser[enter][nIndexm].compareTo(" ") == 0){
	DifUser[enter][nIndexm] = User[nIndexi][1];
	break;
       }/* End if.*/
      }/* End for.*/
    }/* End if.*/
   }
  }/* End for.*/
   
  System.out.print("Object \t");
  for(int nIndexj = 0; nIndexj < ObjectSize; nIndexj++){
    char FirstChar = (char)DifObject[nIndexj].charAt(0);
    System.out.print(FirstChar);
    String RemainChars = DifObject[nIndexj].substring(1);
    System.out.print(RemainChars+"\t ");
   }/* End if.*/

   System.out.println("\nDomain");
   for(int nIndexj = 0; nIndexj < DomainSize; nIndexj++){
    System.out.print(DifDomain[nIndexj][0]+"\t ");
    for(int nIndexk = 1; nIndexk <= ObjectSize; nIndexk++){
     if(DifDomain[nIndexj][nIndexk] != " ")
      System.out.print(DifDomain[nIndexj][nIndexk].toUpperCase());
      System.out.print("\t ");
     }/* End if.*/
     System.out.println("");
    }/* End for.*/
    System.out.println("Press enter key to continue...");
    getChar();

    System.out.println("User \t Domain(s)");
    for(int nIndexj = 0; nIndexj < UserSize; nIndexj++){
     int first = 0;
     System.out.print(DifUser[nIndexj][0]+"\t ");
     for(int nIndexk = 1; nIndexk <= DomainSize; nIndexk++){
      if(DifUser[nIndexj][nIndexk] != " "){
       if (first > 0) System.out.print(", ");
       System.out.print(DifUser[nIndexj][nIndexk]);
       first++;
      }/*End if.*/
     }
     System.out.println(" ");
    }
    System.out.println("Press enter key to continue...");
    getChar();
 }/* End of Init.*/

 void TakeRequest(){
   /* Initialise System.*/
   Init();
   System.out.println("User \t Resource \t Action \t Result");

   for(int nIndexi = 0; nIndexi < DS.nActionEntry; nIndexi++){
    boolean bFound = false;
    boolean bPermission = false;
    boolean UserType = false;
    boolean DomainType = false;
    int UserPos = -1;
    int DomainPos = -1;
    int ObjPos = -1;

    if(Action[nIndexi][2] != null){
     char Ch[]  = new char[1];
     Ch[0]  = Action[nIndexi][0].charAt(0);
     Ch[0] = (char)(Ch[0] - 32);
     String Name = new String(Ch);
     Name = Name + 
     (Action[nIndexi][0].substring(1,Action[nIndexi][0].length()));
     System.out.print(Name+" \t "+Action[nIndexi][1]+"     \t "+Action[nIndexi][2].toUpperCase()+" \t \t ");
     for(int nIndexh = 0; nIndexh < ObjectSize; nIndexh++){
      if(Action[nIndexi][1].compareTo(DifObject[nIndexh]) == 0){
       ObjPos = nIndexh+1;
       break;
      }/* End if.*/
     }
     for(int nIndexj = 0; nIndexj < UserSize; nIndexj++){
      if(Action[nIndexi][0].compareTo(DifUser[nIndexj][0]) == 0){
       for(int nIndexk = 1; nIndexk <= DomainSize; nIndexk++){
	for(int nIndexm = 0; nIndexm < DomainSize; nIndexm++){
	  if(DifUser[nIndexj][nIndexk].compareTo(DifDomain[nIndexm][0]) == 0){
	   UserPos = nIndexj;
	   DomainPos = nIndexm;
	   String temp = DifDomain[nIndexm][ObjPos];
	   /*Check if the domain has bPermission to access the resource.*/
	   if(temp.compareTo(" ") == 0) DomainType = false;
	   else{
	    DomainType = true;
	    bPermission = false;
	    int length = temp.length();
	    for (int nn = 0; nn < length; nn++){  
	     if(temp.charAt(nn) == (Action[nIndexi][2].charAt(0))){
	      System.out.println ("Granted");
	      bFound = true;
	      bPermission = true;
	      nn = length; nIndexm = DomainSize; 
	      nIndexk = DomainSize+1; nIndexj = UserSize;
	      break;
	     }/* End if.*/
	    }/*End for.*/
	    break;
	   }/* End else.*/
	   nIndexk = DomainSize+1; nIndexm = DomainSize+1;
	    }/*End if.*/
	   }/*End for.*/
	  }/*End for*/
	  break;
	  }/*End if.*/
	  }/*End for.*/
	  
	  if(bFound == false){
	   if(UserPos < 0)System.out.println("Denied, no such user exists");
	   else if(ObjPos < 0)System.out.println("Denied, no such object exists");
	   else if (DomainPos < 0)System.out.println("Denied, user does not access to a domain");
	   else{
	   if(DomainType == true){
	    if(bPermission == false){
	     int first = 0;
	     System.out.print("Denied, domain ");
	     for(int nIndexk = 1; nIndexk <= DomainSize; nIndexk++){       
	      if(DifUser[UserPos][nIndexk] != " "){
	       if (first > 0) System.out.print(", ");
		System.out.print(DifUser[UserPos][nIndexk]);
		first++;
	       }/* End if.*/
	      }/* End if.*/
	      System.out.print (" does not have ");
	      if(Action[nIndexi][2].compareTo("r") == 0) 
		System.out.print("read");
	      else if(Action[nIndexi][2].compareTo("w") == 0)
		    System.out.print("write");
	      else if(Action[nIndexi][2].compareTo("x") == 0)
		    System.out.print("execute");
	      System.out.println(" access.");
	     }/* End for.*/
	    }/* End if.*/
	   else{
	    int first = 0;
	    System.out.print("Denied, domain ");
	    for(int nIndexk = 1; nIndexk <= DomainSize; nIndexk++){       
	     if(DifUser[UserPos][nIndexk] != " "){
	      if (first > 0) System.out.print(", ");
	       System.out.print(DifUser[UserPos][nIndexk]);
	       first++;
	      }/* End if.*/
	     }/* End if.*/
	     System.out.println (" does not have access to device.");
	    }/* End if.*/
	   }/* End if.*/
	 }/*End of if for bFound*/
       }/*End of If.*/
       else{       
	boolean FoundIt = false;
	char Ch[]  = new char[1];
	Ch[0]  = Action[nIndexi][0].charAt(0);
	Ch[0] = (char)(Ch[0] - 32);
	String Name = new String(Ch);
	Name = Name + 
	(Action[nIndexi][0].substring(1,Action[nIndexi][0].length()));
	System.out.print(Name+" \t  \t \t Changed \t ");
	String DomAcc = " ";
	int xx = 0, yy = 0;
	for(int nIndexj = 0; nIndexj < UserSize; nIndexj++){
	 if(Action[nIndexi][0].compareTo(DifUser[nIndexj][0]) == 0){
	  for(int nIndexk = 1; nIndexk <= DomainSize; nIndexk++){
	   for(int nIndexm = 0; nIndexm < DomainSize; nIndexm++){
	    if(DifUser[nIndexj][nIndexk].compareTo(DifDomain[nIndexm][0]) == 0){
	     if (DomAcc.compareTo(" ") == 0){
	      DomAcc = DifUser[nIndexj][nIndexk];
	      xx = nIndexj;
	      yy = nIndexk;
	     }/* End if.*/
	    
	    if (Action[nIndexi][1].compareTo(DomAcc)== 0){
	     System.out.println("Granted, Its already at "+Action[nIndexi][1]);
	     FoundIt = true;
	     nIndexm = DomainSize; nIndexk = DomainSize+1; nIndexj = UserSize;
	    }/* End if.*/
	    else{
	     if(Action[nIndexi][1].compareTo(DifUser[nIndexj][nIndexk]) == 0){
	      System.out.println("Granted, from "+DomAcc+" to: "+
				  Action[nIndexi][1]);
	      DifUser[xx][yy] = Action[nIndexi][1];
	      DifUser[nIndexj][nIndexk] = DomAcc;
	      FoundIt = true;
	     }/* End if.*/
	    }/* End if.*/
	   }/* End if.*/
	 }/*End for.*/
	}/*End for.*/
       }/*End for.*/
      }/*End for.*/
      if (FoundIt == false)
       System.out.println("Denied, User does not have access to domain "+
       Action[nIndexi][1]);
     }/*End of else.*/
    }/*End for.*/
 }/*End of TakeRequest.*/
}/* End of DomainArbitrator.*/



