Package org.w3c.jigsaw.pics

Source Code of org.w3c.jigsaw.pics.SampleLabel

// SampleLabel.java
// $Id: SampleLabel.java,v 1.7 2000/08/16 21:37:43 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.pics ;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberInputStream;
import java.io.PrintStream;
import java.io.StringBufferInputStream;

// I like writing these silly kind of parsers !
// (its probably the X)

class LabelParser {
    File file = null ;
    LineNumberInputStream in = null ;
    int         ch = -1 ;
    byte buffer[] = null ;
    int  bufptr = 0 ;

    /**
     * Append the given char in the internal buffer
     */

    public void append (int ch) {
  if ( bufptr + 1 >= buffer.length) {
      // resize buffer
      byte nbuf[] = new byte[buffer.length * 2] ;
      System.arraycopy (buffer, 0, nbuf, 0, bufptr) ;
      buffer = nbuf ;
  }
  buffer[bufptr++] = (byte) ch ;
    }

    /**
     * Get the token from our internale buffer.
     */

    public String getToken (boolean clear) {
  String tok = new String (buffer, 0, 0, bufptr) ;
  if ( clear )
      bufptr = 0 ;
  return tok ;
    }

    /**
     * Parser expects given character.
     */

    void expect (int c)
  throws InvalidLabelException
    {
  if ( ch == c )
      return ;
  String msg = ("expected "
          + (new Character((char) c)).toString()
          + "[" + c + "]"
          + " got "
          + (new Character((char) ch)).toString()
          + "[" + ch + "]");
  if (file == null)
    throw new InvalidLabelException(in.getLineNumber(), msg) ;
  else
    throw new InvalidLabelFileException (file, in.getLineNumber(), msg) ;
    }

    String parseVariableName ()
  throws IOException
    {
  while ((ch != '=') && (ch != '\n') && (ch != -1)) {
      append (Character.toLowerCase((char)ch)) ;
      ch = in.read() ;
  }
  return getToken(true) ;
    }

    String parseVariableValue()
  throws IOException
    {
  while ( (ch != -1) && (ch != '\n') ) {
      append (ch) ;
      ch = in.read() ;
  }
  return getToken(true) ;
    }

    SampleLabel parse (SampleLabel into)
  throws InvalidLabelException, InvalidLabelFileException
    {
  try {
      while ( true ) {
    switch (ch) {
      case -1:
          // we are done.
          return into ;
      case ' ': case '\t': case '\n':
          ch = in.read() ;
          continue ;
      case '#':
          while ( ((ch = in.read()) != '\n') && (ch != -1) )
        ;
          continue ;
      default:
          String name = parseVariableName() ;
          expect ('=') ; ch = in.read() ;
          String value = parseVariableValue() ;
          if (ch != -1) { // Pb -1 instead of \n
      expect ('\n') ;
      ch = in.read() ;
          }
          into.addBinding (name, value) ;
          continue ;
    }
      }
  } catch (IOException e) {
    if (file == null)
      throw new InvalidLabelException( "IO exception.") ;
    else
      throw new InvalidLabelFileException (file.getAbsolutePath()
             + ": IO exception.") ;
  }
    }

    LabelParser (File file)
  throws InvalidLabelFileException
    {
  this.file = file ;
  try {
      this.in = (new LineNumberInputStream
           (new BufferedInputStream
      (new FileInputStream (file)))) ;
      this.buffer = new byte[32] ;
      this.ch = in.read() ;
  } catch (IOException e) {
      throw new InvalidLabelFileException (file.getAbsolutePath()
             + ": IO exception.") ;
  }
    }

    LabelParser (String string)
  throws InvalidLabelException
    {
  try {
      this.in = (new LineNumberInputStream
           (new BufferedInputStream
      (new StringBufferInputStream (string)))) ;

      this.buffer = new byte[32] ;
      this.ch = in.read() ;
  } catch (IOException e) {
      throw new InvalidLabelException( "IO exception.") ;
  }
    }

}

/**
* Label internal representation.
* The server has to know something about labels. In this implementation, I try
* to reduce this knowledge as fas as I could. Here, a label is a set of
* assignements to variables (options in PICS terms), and a rating.
* The syntax for writing label files is the following:
* <variable>=<value>\n
* <p>Comments are allowed through the '#' at beginning of line.
* With the special variable 'ratings' being mandatory.
*/

public class SampleLabel implements LabelInterface {
    // Default variables array size
    private static final int VARSIZE = 8 ;

    String vars[] = null ;
    String vals[] = null ;

    int    varptr = 0 ;

    void addBinding (String var, String val) {
  if ( varptr + 1 >= vars.length ) {
      // resize arrays
      String nvars[] = new String[vars.length*2] ;
      String nvals[] = new String[vals.length*2] ;
      System.arraycopy (vars, 0, nvars, 0, vars.length) ;
      System.arraycopy (vals, 0, nvals, 0, vals.length) ;
      vars = nvars ;
      vals = nvals ;
  }
  vars[varptr] = var ;
  vals[varptr] = val ;
  varptr++ ;
    }

    /**
     * Debugging: print the given options of this label.
     * @param out The PrintStream to print to.
     */

    public void print (PrintStream out) {
  for (int i = 0 ; i < varptr ; i++) {
      System.out.println ("\t" + vars[i] + " = " + vals[i]) ;
  }
    }

    /**
     * Does this label defines the given option ?
     * @param option The option to look for.
     * @return <strong>true</strong> if the label defines the given option.
     */

    public boolean hasOption (String option) {
  for (int i = 0 ; i < varptr ; i++) {
      if ( vars[i].equals (option) )
    return true ;
  }
  return false ;
    }

    /**
     * Get an option index.
     * This allows for fast acces to label options. There is no guarantee that
     * the same option will get the same index across labels.
     * @param option The option to look for.
     * @return An integer, which is the option index if the option was found
     *    or <strong>-1</strong> if the option isn't defined for this label.
     */

    public int getOptionIndex (String option) {
  for (int i = 0 ; i < varptr ; i++) {
      if ( vars[i].equals (option) )
    return i;
  }
  return -1 ;
    }

    /**
     * Get an option value, by index.
     * This, along with the <strong>getOptionIndex</strong> method provides
     * a fast access to option values.
     * @param idx The index of the option, as gotten from
     *    <strong>getOptionIndex</strong>.
     * @return A String instance, providing the option value.
     */

    public String getOptionValue (int idx) {
  if ( (idx < 0) || (idx >= varptr) )
      throw new RuntimeException (this.getClass().getName()
          + "[getOptionValue]: "
          + " invalid index.") ;
  return vals[idx] ;
    }

    /**
     * Get an option value, by option name.
     * @param option The option that you want the value of.
     * @return A String instance giving the option value, or
     *    <strong>null</strong>, if the option isn't defined for this label.
     */

    public String getOptionValue (String option) {
  for (int i = 0 ; i < varptr ; i++) {
      if ( vars[i].equals (option) )
    return vals[i] ;
  }
  return null ;
    }

    /**
     * Is this label generic ?
     * @return <strong>true</strong> if the label if generic.
     */

    public boolean isGeneric () {
  int idx = getOptionIndex ("generic") ;
  if ( idx >= 0 )
      return (new Boolean(getOptionValue (idx))).booleanValue() ;
  return false ;
    }

    /**
     * Emit the given option to the output.
     * If the option is not defined for this label, skip it (don't emit). If
     * possible, and according to the format, emit the short option name.
     * @param space Should we emit a leading space.
     * @param option The option name.
     * @return <strong>true</strong> if the option was successfully emited,
     *    <strong>false</strong> otherwise.
     */

    private boolean emit (boolean space
        , StringBuffer into
        , String option, int format) {
  String value = getOptionValue (option) ;
  if ( value != null ) {
      switch (format) {
        case LabelBureauInterface.FMT_MINIMAL:
        case LabelBureauInterface.FMT_SHORT:
      // emit short option name
      if ( space )
          into.append (" ") ;
      into.append (option+" "+value) ;
      break ;
        default:
      // emit full option name
      if ( space )
          into.append (" ") ;
      into.append (option+" "+value) ;
      break ;
      }
      return true ;
  }
  return false ;
    }

    /**
     * Emit the given option to the output.
     * If possible, and according to the format, emit the short option name.
     * @param space Should we emit a leading space.
     * @param into The StringBuffer to dump this label to.
     * @param option The option name.
     */

    private void emit (boolean space, StringBuffer into, int idx, int format) {
  switch (format) {
    case LabelBureauInterface.FMT_MINIMAL:
    case LabelBureauInterface.FMT_SHORT:
        // emit short option name
        if ( space )
      into.append (" ") ;
        into.append (vars[idx]+" "+vals[idx]) ;
        break ;
    default:
        if ( space )
      into.append (" ") ;
        into.append (vars[idx]+" "+vals[idx]) ;
  }
    }

    /**
     * Dump this label according to the given format.
     * The dump should take place <em>after</em> the service has dump itself.
     * @param into A StringBuffer to dump the labels to.
     * @param format The format in which the dump should be done. This can
     *    be one of the four format described in the PICS specification.
     */

    public void dump (StringBuffer into, int format) {
  boolean space = false ; ;
  switch (format) {
    case LabelBureauInterface.FMT_MINIMAL:
        // emit just the ratings, except if generic
        if ( isGeneric() ) {
      // emit the generic and for options (FIXME errors ?)
      emit (space,into,"generic",LabelBureauInterface.FMT_MINIMAL);
      space = true ;
      emit (space,into,"for",LabelBureauInterface.FMT_MINIMAL) ;
      emit (space,into,"ratings",LabelBureauInterface.FMT_MINIMAL);
        } else {
      emit (space,into,"ratings",LabelBureauInterface.FMT_MINIMAL);
        }
        break ;
    case LabelBureauInterface.FMT_SHORT:
        // emit ratings, and full, which I deem appropriate
        if ( isGeneric() ) {
      // emit the generic and for options:
      emit (space,into, "generic", LabelBureauInterface.FMT_SHORT);
      space = true ;
      emit (space,into, "for", LabelBureauInterface.FMT_SHORT) ;
      emit (space,into, "full", LabelBureauInterface.FMT_SHORT) ;
      emit (space,into, "ratings", LabelBureauInterface.FMT_SHORT);
        } else {
      emit (space, into, "full", LabelBureauInterface.FMT_SHORT) ;
      space = true ;
      emit (space,into,"ratings",LabelBureauInterface.FMT_SHORT) ;
        }
        break ;
    case LabelBureauInterface.FMT_FULL:
        // Emit all options, rating at the end
        for (int i = 0 ; i < varptr ; i++) {
      if ( vars[i].equals("ratings") )
          continue ;
      emit (space, into, i, LabelBureauInterface.FMT_FULL) ;
      space = true ;
        }
        emit (space, into, "ratings", LabelBureauInterface.FMT_FULL) ;
        break ;
    case LabelBureauInterface.FMT_SIGNED:
        throw new RuntimeException (this.getClass().getName()
            + "[dump]: "
            + "SIGNED format unsupported.") ;
       
        // not reached
    default:
        throw new RuntimeException (this.getClass().getName()
            + "[dump]: "
            + " invalid format "
            + "\"" + format + "\"") ;
  }
    }

    /**
     * Create a new label from the given stream.
     * @param file The file inwhich the label options are described.
     */

    SampleLabel (File file)
  throws InvalidLabelException
    {
      try {
  this.vars   = new String[VARSIZE] ;
  this.vals   = new String[VARSIZE] ;
  this.varptr = 0 ;
  LabelParser p = new LabelParser (file) ;
  p.parse (this) ;
      } catch (InvalidLabelException e) {
  throw new InvalidLabelFileException(e.getMessage());
      }
    }

    SampleLabel (String string)
  throws InvalidLabelException
    {
  this.vars   = new String[VARSIZE] ;
  this.vals   = new String[VARSIZE] ;
  this.varptr = 0 ;
  LabelParser p = new LabelParser (string) ;
  p.parse (this) ;
    }
    /**
     * Create a new label from a set of options.
     * This constructor takes two arrays, one of option names, and one
     * of option values. It builds out of them the internal
     * representation for this label.
     * <p>The given arrays are used as is (no copy), and might side-effected
     * by the new instance.
     * @param optnames Names of option for this label.
     * @param optvalues Values of option for this label. 
     */

    public SampleLabel (String optnames[], String optvals[]) {
  if ( optnames.length != optvals.length )
      throw new RuntimeException (this.getClass().getName()
          + " invalid constructor params:"
          + " bad length.") ;
  this.vars   = optnames ;
  this.vals   = optvals ;
  this.varptr = optnames.length ;
    }

    // Testing only

    public static void main (String args[]) {
  if ( args.length != 1 ) {
      System.out.println ("Label <file>") ;
      System.exit (1) ;
  }
  try {
      SampleLabel label = new SampleLabel (new File (args[0])) ;
      StringBuffer sb = new StringBuffer() ;
      label.dump (sb, LabelBureauInterface.FMT_MINIMAL) ;
      System.out.println (sb.toString()) ;
  } catch (InvalidLabelException e) {
      System.out.println (e.getMessage()) ;
      System.exit (1) ;
  }
  System.exit (0) ;
    }

}

TOP

Related Classes of org.w3c.jigsaw.pics.SampleLabel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.