Package org.drools.clips

Source Code of org.drools.clips.ClipsShell$GlobalResolver2

/**
*
*/
package org.drools.clips;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.PrintStream;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.antlr.runtime.ANTLRReaderStream;
import org.antlr.runtime.CommonTokenStream;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.base.ClassTypeResolver;
import org.drools.base.mvel.DroolsMVELFactory;
import org.drools.clips.functions.AssertFunction;
import org.drools.clips.functions.BindFunction;
import org.drools.clips.functions.CallFunction;
import org.drools.clips.functions.CreateListFunction;
import org.drools.clips.functions.EqFunction;
import org.drools.clips.functions.GetFunction;
import org.drools.clips.functions.IfFunction;
import org.drools.clips.functions.LessThanFunction;
import org.drools.clips.functions.LessThanOrEqFunction;
import org.drools.clips.functions.MinusFunction;
import org.drools.clips.functions.ModifyFunction;
import org.drools.clips.functions.MoreThanFunction;
import org.drools.clips.functions.MoreThanOrEqFunction;
import org.drools.clips.functions.MultiplyFunction;
import org.drools.clips.functions.NewFunction;
import org.drools.clips.functions.PlusFunction;
import org.drools.clips.functions.PrintoutFunction;
import org.drools.clips.functions.PrognFunction;
import org.drools.clips.functions.ReturnFunction;
import org.drools.clips.functions.RunFunction;
import org.drools.clips.functions.SetFunction;
import org.drools.clips.functions.SwitchFunction;
import org.drools.common.InternalRuleBase;
import org.drools.compiler.PackageBuilder;
import org.drools.lang.descr.AttributeDescr;
import org.drools.lang.descr.FunctionDescr;
import org.drools.lang.descr.ImportDescr;
import org.drools.lang.descr.PackageDescr;
import org.drools.lang.descr.RuleDescr;
import org.drools.lang.descr.TypeDeclarationDescr;
import org.drools.rule.ImportDeclaration;
import org.drools.rule.MVELDialectRuntimeData;
import org.drools.rule.Namespaceable;
import org.drools.rule.Package;
import org.drools.runtime.Globals;
import org.drools.runtime.rule.FactHandle;
import org.drools.spi.GlobalResolver;
import org.mvel2.MVEL;
import org.mvel2.ParserContext;
import org.mvel2.compiler.ExpressionCompiler;

/**
* An interactive Clips session shell.
* You can launch this as a Main class, no parameters are required.
* @author Michael Neale
*
*/
public class ClipsShell
    implements
    ParserHandler,
    VariableContext,
    FunctionContext,
    PrintRouterContext {
    private Map<String, Object> vars;

    private PackageBuilder      packageBuilder;
    private RuleBase            ruleBase;
    private StatefulSession     session;

    // private Map                 functions;

    //    private Map                 directImports;
    //    private Set                 dynamicImports;

    private ClassTypeResolver   typeResolver;

    private String              moduleName;
    private static final String MAIN = "MAIN";

    private DroolsMVELFactory   factory;

    public ClipsShell() {
        this( RuleBaseFactory.newRuleBase() );
    }

    public static void main(String[] args) throws Exception {


        StringBuffer buf = new StringBuffer();
        FunctionHandlers handlers = FunctionHandlers.getInstance();
        handlers.registerFunction( new PlusFunction() );
        handlers.registerFunction( new MinusFunction() );
        handlers.registerFunction( new MultiplyFunction() );
        handlers.registerFunction( new ModifyFunction() );
        handlers.registerFunction( new CreateListFunction() );
        handlers.registerFunction( new PrintoutFunction() );
        handlers.registerFunction( new PrognFunction() );
        handlers.registerFunction( new IfFunction() );
        handlers.registerFunction( new LessThanFunction() );
        handlers.registerFunction( new LessThanOrEqFunction() );
        handlers.registerFunction( new MoreThanFunction() );
        handlers.registerFunction( new MoreThanOrEqFunction() );
        handlers.registerFunction( new EqFunction() );
        handlers.registerFunction( new SwitchFunction() );
        //handlers.registerFunction( new DeffunctionFunction() );
        handlers.registerFunction( new ReturnFunction() );
        handlers.registerFunction( new RunFunction() );
        handlers.registerFunction( new BindFunction() );
        handlers.registerFunction( new NewFunction() );
        handlers.registerFunction( new SetFunction() );
        handlers.registerFunction( new GetFunction() );
        handlers.registerFunction( new CallFunction() );
        handlers.registerFunction( new AssertFunction() );
        ClipsShell shell = new ClipsShell();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        shell.addRouter( "t", new PrintStream( out ) );

        System.out.print("Drools>");

        StringBuffer sessionLog = new StringBuffer();
        while(true) {
            byte name[] = new byte[256];

          System.in.read(name);
          String cmd = (new String(name)).trim();

          //System.out.println("ECHO:" + cmd);

          if (cmd.equals("(exit)") || cmd.equals("(quit)")) {
            sessionLog.append(cmd);
            break;
          }
          buf.append(cmd);

          if (isBalancedBrackets(buf)) {
            String exp = buf.toString();
            if (exp.startsWith("(save ")) {
              String file = getFileName(exp);
              System.out.println("Saving transcript to [" + file + "]");
              writeFile(file, sessionLog);
              sessionLog = new StringBuffer();
              System.out.print("Drools>");
            } else {
              sessionLog.append(cmd + "\n");

              if (exp.startsWith("(load ")) {
                String file = getFileName(exp);
                System.out.println("Loading transcript from [" + file + "]");
                exp = loadFile(file);
              }

              shell.eval(exp);
              String output = new String(out.toByteArray());
              if (output != null && output.trim().length() > 0) {
                System.out.println(output);
              }
              out.reset();
              System.out.print("Drools>");
              buf = new StringBuffer();
            }
          }
        }

        System.out.println("Goodbye, and good luck !");

    }

  private static String loadFile(String fileName) throws IOException {
    File f = new File(fileName);
        InputStream is = new FileInputStream(f);

        long length = f.length();
        byte[] bytes = new byte[(int)length];

        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
            offset += numRead;
        }

        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+f.getName());
        }

        is.close();
    return new String(bytes);
  }

  private static String getFileName(String exp) {
    char qt = '\'';
    if (exp.contains("\"")) {
      qt = '"';
    }
    String file = exp.substring(exp.indexOf(qt) + 1, exp.lastIndexOf(qt));
    return file;
  }

    private static void writeFile(String file, StringBuffer sessionLog) {
      FileOutputStream fout;
    try {
      File f = new File(file);
      if (!f.exists()) {
        f.createNewFile();
      }
      fout = new FileOutputStream(f);
      fout.write(sessionLog.toString().getBytes());
      fout.flush();
      fout.close();
    } catch (FileNotFoundException e) {
      System.err.println("File " + file + " does not exist.");
    } catch (IOException e) {
      e.printStackTrace();
    }


  }

  private static boolean isBalancedBrackets(StringBuffer buf) {
    char[] cs = buf.toString().toCharArray();
    int stack = 0;
    for (int i = 0; i < cs.length; i++) {
      if (cs[i] == '(') stack++;
      if (cs[i] == ')') stack--;
    }
    return stack == 0;
  }

  public ClipsShell(RuleBase ruleBase) {
        this.moduleName = MAIN;
        this.ruleBase = ruleBase;

        this.packageBuilder = new PackageBuilder( this.ruleBase );

        this.session = this.ruleBase.newStatefulSession();
        // this.functions = new HashMap();
        //        this.directImports = new HashMap();
        //        this.dynamicImports = new HashSet();

        //        this.typeResolver = new ClassTypeResolver( new HashSet(),
        //                                                   ((InternalRuleBase) this.ruleBase).getConfiguration().getClassLoader() );

        this.factory = (DroolsMVELFactory) new DroolsMVELFactory( null,
                                                                  null,
                                                                  ((InternalRuleBase) this.ruleBase).getGlobals() );

        this.vars = new HashMap<String, Object>();
        GlobalResolver2 globalResolver = new GlobalResolver2( this.vars,
                                                              this.session.getGlobalResolver() );
        this.session.setGlobalResolver( globalResolver );

        this.factory.setContext( null,
                                 null,
                                 null,
                                 this.session,
                                 this.vars );

        addRouter( "t",
                   System.out );
    }

    public StatefulSession getStatefulSession() {
        return this.session;
    }

    public static class GlobalResolver2
        implements
        GlobalResolver {
        private Map<String, Object> vars;
        private GlobalResolver      delegate;

        public GlobalResolver2() {
        }

        public GlobalResolver2(Map<String, Object> vars,
                               GlobalResolver delegate) {
            this.vars = vars;
            this.delegate = delegate;
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            vars = (Map<String, Object>) in.readObject();
            delegate = (GlobalResolver) in.readObject();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject( vars );
            out.writeObject( delegate );
        }

        public Object resolveGlobal(String identifier) {
            Object object = this.vars.get( identifier );
            if ( object == null ) {
                object = delegate.resolveGlobal( identifier );
            }
            return object;
        }

        public void setGlobal(String identifier,
                              Object value) {
            this.delegate.setGlobal( identifier,
                                     value );
        }
    }

    public void importHandler(ImportDescr descr) {
        // use the current focus as the default namespace for these imports
        PackageDescr pkgDescr = createPackageDescr( this.session.getAgenda().getFocusName() );
        pkgDescr.addImport( descr );
        this.packageBuilder.addPackage( pkgDescr );
    }

    public void functionHandler(FunctionDescr functionDescr) {
        // for now all functions are in MAIN
        //setModuleName( functionDescr );
        functionDescr.setNamespace( "MAIN" );
        Appendable builder = new StringBuilderAppendable();

        // strip lead/trailing quotes
        String name = functionDescr.getName().trim();
        if ( name.charAt( 0 ) == '"' ) {
            name = name.substring( 1 );
        }

        if ( name.charAt( name.length() - 1 ) == '"' ) {
            name = name.substring( 0,
                                   name.length() - 1 );
        }
        builder.append( "function " + name + "(" );

        for ( int i = 0, length = functionDescr.getParameterNames().size(); i < length; i++ ) {
            builder.append( functionDescr.getParameterNames().get( i ) );
            if ( i < length - 1 ) {
                builder.append( ", " );
            }
        }

        builder.append( ") {\n" );
        List list = (List) functionDescr.getContent();
        for ( Iterator it = list.iterator(); it.hasNext(); ) {
            FunctionHandlers.dump( (LispForm) it.next(),
                                   builder );
        }
        builder.append( "}" );

        functionDescr.setContent( builder.toString() );
        functionDescr.setDialect( "clips" );

        PackageDescr pkgDescr = createPackageDescr( functionDescr.getNamespace() );
        pkgDescr.addFunction( functionDescr );

        this.packageBuilder.addPackage( pkgDescr );
    }

    public void lispFormHandler(LispForm lispForm) {
        StringBuilderAppendable appendable = new StringBuilderAppendable();
        FunctionHandlers.dump( lispForm,
                               appendable );

        ParserContext context = new ParserContext();
       

        String namespace = this.session.getAgenda().getFocusName();

        Package pkg = this.ruleBase.getPackage( namespace );
        if ( pkg == null ) {
            this.packageBuilder.addPackage( createPackageDescr( namespace ) );
            pkg = this.ruleBase.getPackage( namespace );
           
        }

        if ( pkg != null ) {
            // only time this will be null is if we have yet to do any packagedescr work

            try {
                for ( Iterator it = pkg.getImports().entrySet().iterator(); it.hasNext(); ) {
                    Entry entry = (Entry) it.next();
                    String importName = ((ImportDeclaration) entry.getValue()).getTarget();
                    if ( importName.endsWith( "*" )) {
                        context.addPackageImport( importName.substring( 0,
                                                                        importName.length() - 2 ) );
                    } else {
                     
                        Class cls = ((InternalRuleBase)ruleBase).getRootClassLoader().loadClass( importName );
                        context.addImport( cls.getSimpleName(),
                                           (Class) cls );
                    }
                }

            } catch ( Exception e ) {
                e.printStackTrace();
            }

            MVELDialectRuntimeData data = (MVELDialectRuntimeData) pkg.getDialectRuntimeRegistry().getDialectData( "clips" );
            this.factory.setNextFactory( data.getFunctionFactory() );
        }

        ClassLoader tempClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader( ((InternalRuleBase)ruleBase).getRootClassLoader() );
       
        ExpressionCompiler expr = new ExpressionCompiler( appendable.toString() );
        Serializable executable = expr.compile( context );

        MVEL.executeExpression( executable,
                                this,
                                this.factory );
        Thread.currentThread().setContextClassLoader( tempClassLoader );
    }

    public void templateHandler(TypeDeclarationDescr typeDescr) {
        setModuleName( typeDescr );

        PackageDescr pkg = createPackageDescr( typeDescr.getNamespace() );
        //pkg.addRule( ruleDescr );
        pkg.addTypeDeclaration( typeDescr );

        this.packageBuilder.addPackage( pkg );

        //        try {
        //            this.ruleBase.addPackage( builder.getPackage() );
        //        } catch ( Exception e ) {
        //            e.printStackTrace();
        //        }
    }

    public void ruleHandler(RuleDescr ruleDescr) {
        setModuleName( ruleDescr );
        PackageDescr pkg = createPackageDescr( ruleDescr.getNamespace() );
        pkg.addRule( ruleDescr );

        this.packageBuilder.addPackage( pkg );

        this.session.fireAllRules();

        //        try {
        //            this.ruleBase.addPackage( builder.getPackage() );
        //        } catch ( Exception e ) {
        //            e.printStackTrace();
        //        }
    }

    public void setModuleName(Namespaceable namespaceable) {
        // if the namespace is not set, set it to the current focus module
        if ( isEmpty( namespaceable.getNamespace() ) ) {
            namespaceable.setNamespace( this.session.getAgenda().getFocusName() );
        }
    }

    public boolean isEmpty(String string) {
        return (string == null || string.trim().length() == 0);
    }

    public void eval(String string) {
        eval( new StringReader( string ) );
    }

    public void eval(Reader reader) {
        ClipsParser parser;
        try {
            parser = new ClipsParser( new CommonTokenStream( new ClipsLexer( new ANTLRReaderStream( reader ) ) ) );
            parser.eval( this );
        } catch ( Exception e ) {
            e.printStackTrace();
        }
    }

    public void run() {
        this.session.fireAllRules();
    }

    public void run(int fireLimit) {
        this.session.fireAllRules( fireLimit );
    }

    public FactHandle insert(Object object) {
        return this.session.insert( object );
    }

    public void importEntry(String importEntry) {

    }

    public void addFunction(Function function) {
        this.factory.createVariable( function.getName(),
                                     function );
    }

    public boolean removeFunction(String functionName) {
        return false; //(this.vars.remove( functionName ) != null);
    }

    public Map<String, Function> getFunctions() {
        Map<String, Function> map = new HashMap<String, Function>();
        //        for ( Iterator it = this.vars.entrySet().iterator(); it.hasNext(); ) {
        //            Entry entry = (Entry) it.next();
        //            if ( entry.getValue() instanceof Function ) {
        //                map.put( (String) entry.getKey(),
        //                         (Function) entry.getValue() );
        //            }
        //        }
        return map;
    }

    public void addRouter(String name,
                          PrintStream out) {

        Map routers = (Map) this.vars.get( "printrouters" );
        if ( routers == null ) {
            routers = new HashMap();
            this.factory.createVariable( "printrouters",
                                         routers );
        }

        routers.put( name,
                     out );

    }

    public boolean removeRouter(String name) {
        return false; //(this.vars.remove( name ) != null);
    }

    //    public Map<String, PrintStream> getRouters() {
    //        Map<String, PrintStream> map = new HashMap<String, PrintStream>();
    //        for ( Iterator it = this.vars.entrySet().iterator(); it.hasNext(); ) {
    //            Entry entry = (Entry) it.next();
    //            if ( entry.getValue() instanceof Function ) {
    //                map.put( (String) entry.getKey(),
    //                         (PrintStream) entry.getValue() );
    //            }
    //        }
    //        return map;
    //    }

    public void addVariable(String name,
                            Object value) {
        if ( name.startsWith( "?" ) ) {
            name = name.substring( 1 );
        }
        this.factory.createVariable( name,
                                     value );
        //        this.session.setGlobal( name,
        //                                value );
    }

    //    public void removeVariable(String name) {
    //        String temp = this.varNameMap.get( name );
    //        if ( temp != null ) {
    //            name = temp;
    //        }
    //        this.session.getGlobal( identifier ).remove( name );
    //    }

    private PackageDescr createPackageDescr(String moduleName) {
        PackageDescr pkg = new PackageDescr( moduleName );
        pkg.addAttribute( new AttributeDescr( "dialect",
                                              "clips" ) );

        //        for ( Iterator it = this.typeResolver.getImports().iterator(); it.hasNext(); ) {
        //            pkg.addImport( new ImportDescr( (String) it.next() ) );
        //        }

        return pkg;
    }

}
TOP

Related Classes of org.drools.clips.ClipsShell$GlobalResolver2

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.