All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.internal.util.BitwiseExpression Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/* ****************************************************************************
*
*	File: BitwiseExpressionEvaluator
*
* ****************************************************************************
*
*	ADOBE CONFIDENTIAL
*	___________________
*
*	Copyright 2005 Adobe Systems Incorporated
*	All Rights Reserved.
*
*	NOTICE: All information contained herein is, and remains the property of
*	Adobe Systems Incorporated and its suppliers, if any. The intellectual
*	and technical concepts contained herein are proprietary to Adobe Systems
*	Incorporated and its suppliers and may be covered by U.S. and Foreign
*	Patents, patents in process, and are protected by trade secret or
*	copyright law. Dissemination of this information or reproduction of this
*	material is strictly forbidden unless prior written permission is obtained
*	from Adobe Systems Incorporated.
*
* ***************************************************************************/
package com.adobe.internal.util;


import java.util.EmptyStackException;
import java.util.StringTokenizer;

 

/**
**  This is generic utility class for handling Bitwise operations. Currently it handles only  | and &.
*        Precedence is controlled by paranthesis,().
* 
*   This utility uses a "stack" based approach and computes the expression of the result while building the stack.
*   Expression is parsed from the left-right and executed from right-left
* 
*   Expression consists of operands and operators. 
*   
*   sample expression eg. EDIT|MODFIY&DELETE
* 
*   Operators: This utility currently supports | and & operators and will be later expanded to handle even !(NOT).
*   Operands : Operand can be any string literal (EDIT,MODIFY,DELETE) which can be evaluated to boolean result by the registered operandEvaluator.
* 	Precedence : Precedence of the expression can be controlled by parenthesis(). If they are not specified expression is executed from right to left.
* 	     EDIT|MODFIY&DELETE will be treated as EDIT|(MODFIY&DELETE). 
* 
* 	Valid Expressions:
*       X    - single operand expression
* 	    X|Y|Z , X|Y&Z  - precedence is controlled from right-left 
*		(X|Y)&Z  - precedence is controlled by ( ,)
*	
*	InValid Expressions:	
*		X&(Y|Z  - MalformedException - "no closed paranthesis"
*		X&Y| - MalformedException -"Expecting operand after operator |"
*		
*   OperandEvaluator:
*        With the main design goal of keeping this utility generic , logic of computing the boolean value of operand (where EDIT bit is set ?) is pushed to clients.
*        clients need to implement BitwiseOperandEvaluator interface and implement evaluate function. If clients encountera operand variable for which boolean value cannot be
* 		 fetched , it will throw InvalidOperandExceeption.
* 		
* 		 Expression X&A is inValid because value of operand "A" cannot be fetched  	 
* 		
*  @author speri
*
*/
public class BitwiseExpression {
	
	private BitwiseOperandEvaluator m_OperandEvaluator;

   	private ArrayListStack m_OperandStack =new ArrayListStack();
	private ArrayListStack m_OperatorStack = new ArrayListStack();
	
	/**
	** creates a BitwiseExpressionEvaluator
	*  
	*  With the main design goal of keeping this class as generic as possible, logic of fetching each operand is decouple from this class.
	*  Instead it will be implemented by clients and specified through this argument. 
	*
	*
	*/
	public BitwiseExpression( BitwiseOperandEvaluator operandEval)
	{
		m_OperandEvaluator = operandEval;
	}
	

	/**
	** Builds and Evaluates the given Bitwise Expression ,E.g  x & (y | z)
	*  
	*  parses the expression for operands and operators and pushes them in to two seperate stacks.
	*  Fetches the value of each operand by calling back the BitwiseOperandEvaluator , which is set during construction.
	*  Evaluates the expresssion with the () as precedence. 
	*

	*/
	public boolean  evaluateExpression(String expression) throws MalformedExpressionException , InvalidOperandException 
    {
    	StringTokenizer value = new StringTokenizer(expression, "|&()",true);
    	int paranthesisCount = 0;
    	char result = '0';  
    	
    	/* Why  Character Object ? Collections can only store objects, not primitive types like int and char. 
    	 * Primitive types must be placed in a wrapper object before they can be placed in a collection
    	*/
       	while(value.hasMoreTokens())
		{
			String token =value.nextToken();
			
			if(" ".equals(token))  	continue; // skip emprty spaces
						 
			
		    if("|".equals(token))          // push to operator stack
		         m_OperatorStack.push(Character.valueOf('|'));
			
		    else if("&".equals(token) )    // push to operator stack
			   	m_OperatorStack.push(Character.valueOf('&'));
			
		    else if("(".equals(token) )     // to keep tack of well'formedness
		        	paranthesisCount++;
		    
		    else if(")".equals(token) )
		    {
	       		result = evaluteExp();
		    	paranthesisCount--;
		    }
		    else // its a operand which needs to be evaluated...
		    {
		    	boolean bRet = m_OperandEvaluator.evaluate(token);
		    			    	
		    	if(bRet)
		    		m_OperandStack.push(Character.valueOf('1'));
		    	else
		    		m_OperandStack.push(Character.valueOf('0'));
		    }
		}
		if(paranthesisCount != 0 )
			throw new MalformedExpressionException("Invalid expression. Not well formed.");
		
		while(m_OperatorStack.size()>0)  //   rest of the expression with out paranthesis land here.
		{
	    	result = evaluteExp();
	   	}
		
		if(m_OperandStack.size() > 0)  // to handle simple one variable expressions ,which do not have any operators.
		{
			result = ((Character)m_OperandStack.pop()).charValue();
		}
		
		return result == '0' ? false :true;
	}
	
	
	private char evaluteExp() throws  MalformedExpressionException
	{
		Character operand1= null,operand2 = null,operator = null;
		char result='0';
		
		try
		{
			 operand1 = (Character)m_OperandStack.pop();
		}
		catch(EmptyStackException e)
		{
			throw new MalformedExpressionException("Invalid expression. Not well formed.",e);
		}
		
		try
		{
			    operator = (Character)m_OperatorStack.pop();
			 	try
				{
					 operand2 = (Character)m_OperandStack.pop(); 
				}
				catch(EmptyStackException e)
				{
					throw new MalformedExpressionException("Invalid expression. Not well formed.",e);
				}
				if(operator.charValue() == '|')
		    	  result = (char)( operand1.charValue() | operand2.charValue());
		    	if(operator.charValue() == '&')
		    	  result =  (char)((operand1.charValue()) & (operand2.charValue()));
		}
		catch(EmptyStackException e)
		{
			result = ((Character)m_OperandStack.pop()).charValue();   //No Operator,  single variable expression 
		}
		    	
    	if(result == '0')
    		m_OperandStack.push(Character.valueOf('0'));
    	else 
    		m_OperandStack.push(Character.valueOf('1'));
    	return result;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy