Groovy2ElementInfo.java :  » Web-Framework » rife-1.6.1 » com » uwyn » rife » engine » Java Open Source

Java Open Source » Web Framework » rife 1.6.1 
rife 1.6.1 » com » uwyn » rife » engine » Groovy2ElementInfo.java
/*
 * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
 * Distributed under the terms of either:
 * - the common development and distribution license (CDDL), v1.0; or
 * - the GNU Lesser General Public License, v2.1 or later
 * $Id: Groovy2ElementInfo.java 3701 2007-03-18 12:24:23Z gbevin $
 */
package com.uwyn.rife.engine;

import com.uwyn.rife.config.RifeConfig;
import com.uwyn.rife.engine.exceptions.EngineException;
import com.uwyn.rife.engine.exceptions.NotFoundProcessingErrorException;
import com.uwyn.rife.engine.exceptions.ParsingErrorException;
import com.uwyn.rife.engine.exceptions.ProcessingErrorException;
import com.uwyn.rife.ioc.PropertyValueObject;
import com.uwyn.rife.resources.ResourceFinder;
import com.uwyn.rife.resources.exceptions.ResourceFinderErrorException;
import com.uwyn.rife.tools.Convert;
import com.uwyn.rife.tools.InnerClassException;
import com.uwyn.rife.tools.InputStreamUser;
import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import groovy.lang.Script;
import groovy.util.BuilderSupport;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.runtime.InvokerHelper;

class Groovy2ElementInfo implements ElementInfoProcessor
{
  Groovy2ElementInfo()
  {
  }

  public void processElementInfo(ElementInfoBuilder builder, String declarationName, ResourceFinder resourceFinder)
  throws EngineException
  {
    GroovyProcessor processor = new GroovyProcessor(builder);
    
    String processed_path = null;
    try
    {
      // process the element declaration
      try
      {
        processed_path = declarationName;
        processor.processGroovy(processed_path, resourceFinder);
      }
      catch (NotFoundProcessingErrorException e)
      {
        processed_path = DEFAULT_ELEMENTS_PATH+declarationName;
        processor.processGroovy(processed_path, resourceFinder);
      }
    }
    catch (Exception e)
    {
      throw new ProcessingErrorException("element", declarationName, e);
    }
  
    // obtain the modification time
    if (RifeConfig.Engine.getSiteAutoReload())
    {
      URL resource = resourceFinder.getResource(processed_path);
      if (null == resource)
      {
        throw new NotFoundProcessingErrorException("element", processed_path, null);
      }
      
      try
      {
        builder.addResourceModificationTime(new UrlResource(resource, processed_path), resourceFinder.getModificationTime(resource));
      }
      catch (ResourceFinderErrorException e)
      {
        throw new ProcessingErrorException("element", declarationName, "Error while retrieving the modification time.", e);
      }
    }
  }
  
  private class GroovyProcessor extends BuilderSupport
  {
    private ElementInfoBuilder    mElementInfoBuilder = null;
    private String          mGroovyPath = null;

    private  String          mCurrentInput = null;
    private  String          mCurrentOutput = null;
    private  String          mCurrentIncookie = null;
    private  String          mCurrentOutcookie = null;
    private  String          mCurrentParameter = null;
    private ArrayList<String>    mDefaults = null;
    private  SubmissionBuilder    mSubmissionBuilder = null;
    
    private GroovyProcessor(ElementInfoBuilder builder)
    {
      mElementInfoBuilder = builder;
    }
    
    public synchronized void processGroovy(final String groovyPath, ResourceFinder resourceFinder)
    {
      if (null == groovyPath)      throw new IllegalArgumentException("groovyPath can't be null.");
      if (groovyPath.length() == 0)  throw new IllegalArgumentException("groovyPath can't be empty.");
      if (null == resourceFinder)    throw new IllegalArgumentException("resourceFinder can't be null.");
      
      mGroovyPath = groovyPath;

      // retrieve a stream towards the groovy script
      Class script_class = null;
      try
      {
        script_class = resourceFinder.useStream(groovyPath, new InputStreamUser() {
            public Class useInputStream(InputStream stream)
            throws InnerClassException
            {
              if (null == stream)
              {
                throw new NotFoundProcessingErrorException("element", groovyPath, null);
              }
              
              // parse the groovy script and create a class
              GroovyClassLoader mLoader = new GroovyClassLoader(getClass().getClassLoader(), new CompilerConfiguration());
              GroovyCodeSource code_source = new GroovyCodeSource(stream, "elementinfobuilder.groovy", "/groovy/shell");
              try
              {
                return mLoader.parseClass(code_source);
              }
              catch (Throwable e)
              {
                throw new ParsingErrorException("element", groovyPath, e);
              }
            }
          });
      }
      catch (ResourceFinderErrorException e)
      {
        throw new NotFoundProcessingErrorException("element", groovyPath, e);
      }
      
      // setup the script bindings and run it
      Binding binding = new Binding();
      binding.setVariable("processor", this);
      binding.setVariable("builder", mElementInfoBuilder);
      Script script = InvokerHelper.createScript(script_class, binding);
      script.run();
    }
    
    protected void setParent(Object parent, Object child)
    {
//      System.out.println("setParent "+parent+", "+child);
    }
    
    protected Object createNode(Object node)
    {
      return createNode(node, null, null);
    }
    
    protected Object createNode(Object node, Object value)
    {
      return createNode(node, null, value);
    }
    
    protected Object createNode(Object node, Map attributes)
    {
      return createNode(node, attributes, null);
    }
    
    protected Object createNode(Object node, Map atts, Object value)
    {
//      System.out.println("createNode "+qName+", "+atts+", "+value);
      
      if (null == atts)
      {
        atts = new HashMap();
      }

      if (node.equals("element"))
      {
        String  content_type = Convert.toString(atts.get("contenttype"));
        String  extending = Convert.toString(atts.get("extends"));
        String  implementation = Convert.toString(atts.get("implementation"));
        
        mElementInfoBuilder.setContentType(content_type);
        
        // process the class it extends from
        if (extending != null)
        {
          mElementInfoBuilder.extendsFrom(extending);
        }
        
        if (implementation != null)
        {
          mElementInfoBuilder.setImplementation(implementation);
        }
      }
      else if (node.equals("property"))
      {
        mElementInfoBuilder.addStaticProperty(Convert.toString(atts.get("name")), new PropertyValueObject(value));
      }
      else if (node.equals("input"))
      {
        mCurrentInput = Convert.toString(atts.get("name"));
        mDefaults = new ArrayList<String>();
      }
      else if (node.equals("inbean"))
      {
        String classname = Convert.toString(atts.get("classname"));
        String prefix = Convert.toString(atts.get("prefix"));
        String name = Convert.toString(atts.get("name"));
        String group = Convert.toString(atts.get("group"));
        
        mElementInfoBuilder.addInBean(classname, prefix, name, group);
      }
      else if (node.equals("output"))
      {
        mCurrentOutput = Convert.toString(atts.get("name"));
        mDefaults = new ArrayList<String>();
      }
      else if (node.equals("outbean"))
      {
        String classname = Convert.toString(atts.get("classname"));
        String prefix = Convert.toString(atts.get("prefix"));
        String name = Convert.toString(atts.get("name"));
        String group = Convert.toString(atts.get("group"));

        mElementInfoBuilder.addOutBean(classname, prefix, name, group);
      }
      else if (node.equals("incookie"))
      {
        mCurrentIncookie = Convert.toString(atts.get("name"));
        mDefaults = new ArrayList<String>();
      }
      else if (node.equals("outcookie"))
      {
        mCurrentOutcookie = Convert.toString(atts.get("name"));
        mDefaults = new ArrayList<String>();
      }
      else if (node.equals("childtrigger"))
      {
        mElementInfoBuilder.addChildTrigger(Convert.toString(atts.get("name")));
      }
      else if (node.equals("submission"))
      {
        mSubmissionBuilder = mElementInfoBuilder.enterSubmission(Convert.toString(atts.get("name")));
        
        boolean  cancel_continuations = false;        
        String  continuations = Convert.toString(atts.get("continuations"));
        if (continuations != null &&
          continuations.equals("cancel"))
        {
          cancel_continuations = true;
        }
        
        mSubmissionBuilder.cancelContinuations(cancel_continuations);
      }
      else if (node.equals("param"))
      {
        if (Convert.toString(atts.get("name")) != null &&
          Convert.toString(atts.get("regexp")) != null)
        {
          throw new ParsingErrorException("element", mGroovyPath, "A submission parameter can't have both a name and a regexp attribute.", null);
        }
        
        if (Convert.toString(atts.get("name")) != null)
        {
          mCurrentParameter = Convert.toString(atts.get("name"));
          mDefaults = new ArrayList<String>();
        }
        else if (Convert.toString(atts.get("regexp")) != null)
        {
          mSubmissionBuilder.addParameterRegexp(Convert.toString(atts.get("regexp")));
          mDefaults = null;
        }
        else
        {
          throw new ParsingErrorException("element", mGroovyPath, "A submission parameter needs either a name or a regexp attribute.", null);
        }
      }
      else if (node.equals("bean"))
      {
        String classname = Convert.toString(atts.get("classname"));
        String prefix = Convert.toString(atts.get("prefix"));
        String name = Convert.toString(atts.get("name"));
        String group = Convert.toString(atts.get("group"));
        
        mSubmissionBuilder.addBean(classname, prefix, name, group);
      }
      else if (node.equals("file"))
      {
        mSubmissionBuilder.addFile(Convert.toString(atts.get("name")));
      }
      else if (node.equals("defaultvalue"))
      {
        if (null == mDefaults)
        {
          throw new ParsingErrorException("element", mGroovyPath, "A submission parameter that's defined by a regular expression can't have default values.", null);
        }
        
        mDefaults.add((String)value);
      }
      else if (node.equals("exit"))
      {
        mElementInfoBuilder.addExit(Convert.toString(atts.get("name")));
      }
      else
      {
        throw new ParsingErrorException("element", mGroovyPath, "Unsupport element name '"+node+"'.", null);
      }
      
      return node;
    }
    
    protected void nodeCompleted(Object parent, Object node)
    {
//      System.out.println("nodeCompleted "+parent+", "+node);
      
      if (node.equals("input"))
      {
        String[]  defaults = null;
        if (mDefaults.size() > 0)
        {
          defaults = new String[mDefaults.size()];
          defaults = mDefaults.toArray(defaults);
        }
        mElementInfoBuilder.addInput(mCurrentInput, defaults);
        mCurrentInput = null;
        mDefaults = null;
      }
      else if (node.equals("output"))
      {
        String[]  defaults = null;
        if (mDefaults.size() > 0)
        {
          defaults = new String[mDefaults.size()];
          defaults = mDefaults.toArray(defaults);
        }
        mElementInfoBuilder.addOutput(mCurrentOutput, defaults);
        mCurrentOutput = null;
        mDefaults = null;
      }
      else if (node.equals("incookie"))
      {
        String defaultValue = null;
        if (mDefaults.size() > 0)
        {
          defaultValue = mDefaults.get(0);
        }
        mElementInfoBuilder.addIncookie(mCurrentIncookie, defaultValue);
        mCurrentIncookie = null;
        mDefaults = null;
      }
      else if (node.equals("outcookie"))
      {
        String defaultValue = null;
        if (mDefaults.size() > 0)
        {
          defaultValue = mDefaults.get(0);
        }
        mElementInfoBuilder.addOutcookie(mCurrentOutcookie, defaultValue);
        mCurrentOutcookie = null;
        mDefaults = null;
      }
      else if (node.equals("submission"))
      {
        mSubmissionBuilder.leaveSubmission();
      }
      else if (node.equals("param"))
      {
        if (mDefaults != null)
        {
          String[]  defaults = null;
          if (mDefaults.size() > 0)
          {
            defaults = new String[mDefaults.size()];
            defaults = mDefaults.toArray(defaults);
          }
          mSubmissionBuilder.addParameter(mCurrentParameter, defaults);
        }
        mCurrentParameter = null;
        mDefaults = null;
      }
    }
  }
}

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.