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