YAMContext.java
001 /*
002  Copyright (c) 2002 Terence Parr
003  All rights reserved.
004 
005  Redistribution and use in source and binary forms, with or without
006  modification, are permitted provided that the following conditions
007  are met:
008  1. Redistributions of source code must retain the above copyright
009  notice, this list of conditions and the following disclaimer.
010  2. Redistributions in binary form must reproduce the above copyright
011  notice, this list of conditions and the following disclaimer in the
012  documentation and/or other materials provided with the distribution.
013  3. The name of the author may not be used to endorse or promote products
014  derived from this software without specific prior written permission.
015 
016  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
017  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
018  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
019  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
020  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
021  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
022  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
023  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
024  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
025  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
026  */
027 package gate.wiki.antlr;
028 
029 import java.util.Hashtable;
030 import java.util.Vector;
031 import java.util.Stack;
032 
033 /**
034  * Track everything about a translation in progress. Translation targets get
035  * this context. Plugins generate text that must be interpreted as YAM. We
036  * create a new lexer to handle the string, but the new lexer must share context
037  * with the original (enclosing) lexer. This object is what is shared among
038  * lexers.
039  */
040 public class YAMContext{
041   /** Lowest section/overhead level etc... */
042   public static int LOWEST_LEVEL = 1;
043   /** Indication that we are below the lowest level and not in a section */
044   public static int NOT_IN_SECTION_LEVEL = LOWEST_LEVEL - 1;
045   /**
046    * List of package(s) to search for plugin names. CLASSPATH must include dirs
047    * containing package roots listed here.
048    */
049   public static String PLUGINS = "plugins";
050   protected boolean inTable = false;
051   protected Stack listTypeStack = new Stack();
052   protected int sectionLevel = NOT_IN_SECTION_LEVEL;
053   protected StringBuffer textBetweenMarkup = new StringBuffer(1000);
054   protected Stack inputNameStack = new Stack();
055   // Modified by Akshay Java on 1/07/2004
056   // To provide for handling user specified
057   // plugins handlers.
058   /**
059    * A hashtable used to store the user defined markup to plugin class name
060    * mappings.
061    */
062   protected Hashtable userClasses = new Hashtable();
063   protected YAMLexer lexer = null;
064   /** Tracks a list of Class objects */
065   protected Hashtable pluginCache = new Hashtable();
066   protected Hashtable variables = new Hashtable();
067 
068   public YAMContext(YAMLexer lexer){
069     // predefined variables
070     Vector p = new Vector();
071     p.addElement("gate.wiki.antlr.plugin");
072     variables.put(PLUGINS, p);
073     this.lexer = lexer;
074   }
075   public boolean isNestedTranslator(){
076     return inputNameStack.size() 1;
077   }
078   /** The plugins will want to know what the output target language is */
079   public YAMTarget getTarget(){
080     return lexer.getTarget();
081   }
082   public void pushInputName(String name){
083     inputNameStack.push(name);
084   }
085   public String popInputName(){
086     return (String)inputNameStack.pop();
087   }
088   public String getInputName(){
089     return (String)inputNameStack.peek();
090   }
091   /** What line number in the file are we at? */
092   public int getLine(){
093     return lexer.getLine();
094   }
095   /** What column number in the file are we at? */
096   public int getColumn(){
097     return lexer.getColumn();
098   }
099   public Object getVariable(String id){
100     return variables.get(id);
101   }
102   public void defineVariable(String id, Object value){
103     if(getVariable(id!= null){
104       variables.remove(id);
105     }
106     variables.put(id, value);
107   }
108   /**
109    * This method is used for registering the plugin class as the handler for the
110    * specified markup type.
111    
112    @param markup
113    *          the markup that this plugin handles.
114    @param className
115    *          the class name of the plgin.
116    */
117   public void registerClass(String markup, String className){
118     userClasses.put(markup, className);
119   }
120   /** Get from cache or using predefined variable PLUGINS */
121   public Class getPlugin(String name){
122     // System.out.println(getVariable(PLUGINS) + "." + name);
123     Vector plugins = (Vector)getVariable(PLUGINS);
124     for(int i = 0; i < plugins.size(); i++){
125       String pkg = (String)plugins.elementAt(i);
126       String className = pkg + "." + name;
127       if(userClasses.containsKey(name)){
128         className = (String)userClasses.get(name);
129       }
130       try{
131         Class c = Class.forName(className);
132         pluginCache.put(name, c);
133         return c;
134       }catch(ClassNotFoundException cnf){
135         System.err.println("Unknown plugin " + name + "; ignoring...");
136       }
137     }
138     System.err.println("Unknown plugin " + name + "; ignoring...");
139     return null;
140   }
141 }