import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Keeps track of rule "require" statements, definitions and references.
*
* @layer<require>
*/
public class BaliRulesData {
final public static int DEFINED = 1 ;
final public static int REFERENCED = 2 ;
final public static int REQUIRED = 4 ;
final public static int MASK = DEFINED | REFERENCED | REQUIRED ;
/**
* A rule name is defined when it's on the left-hand side of a rule.
*
* @layer<require>
*/
public void addDefinition( String name ) {
setBits( name, DEFINED ) ;
}
/**
* A rule name is referenced when it's used in the right-hand side of a
* rule.
*
* @layer<require>
*/
public void addReference( String name ) {
setBits( name, REFERENCED ) ;
}
/**
* A rule name is required when it's in a "require" statement.
*
* @layer<require>
*/
public void addRequire( String name ) {
setBits( name, REQUIRED ) ;
}
/**
* Return a {@link List} of those names that include given status bits.
*
* @layer<require>
*/
public List getList( int mask, int status ) {
List list = new ArrayList() ;
for ( Iterator p = usageMap.keySet().iterator() ; p.hasNext() ; ) {
String key = ( String ) p.next() ;
if ( ( mask & getStatus( key ) ) == status )
list.add( key ) ;
}
return Arrays.asList( list.toArray( new String [list.size()] ) ) ;
}
/**
* Return the status bits associated with a given name.
*
* @layer<require>
*/
public int getStatus( String name ) {
Integer status = ( Integer ) usageMap.get( name ) ;
return ( status != null ) ? ( MASK & status.intValue() ) : 0 ;
}
/**
* Returns rules that are referenced but neither defined nor in a
* "require" statement.
*
* @layer<require>
*/
public List misDefined() {
return getList( DEFINED | REFERENCED | REQUIRED, REFERENCED ) ;
}
/**
* Specifies the name of the start rule (an implicit reference).
*
* @layer<require>
*/
protected void setStartName( String name ) {
original( name ) ;
addReference( name ) ;
}
/**
* Include bits in the status of a rule name.
*
* @layer<require>
*/
protected void setBits( String name, int bits ) {
usageMap.put( name, STATUS [ ( MASK & bits ) | getStatus( name )] ) ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
final private Map usageMap = new HashMap() ;
final private static Integer[] STATUS = new Integer[] {
null,
new Integer( 1 ),
new Integer( 2 ),
new Integer( 3 ),
new Integer( 4 ),
new Integer( 5 ),
new Integer( 6 ),
new Integer( 7 ),
} ;
}