Package ariba.ui.groovy

Source Code of ariba.ui.groovy.AWXGroovyTag$StatefulComponent

/*
    Copyright 1996-2008 Ariba, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

    $Id: //ariba/platform/ui/demoshell/ariba/ui/groovy/AWXGroovyTag.java#9 $
*/
package ariba.ui.groovy;

import ariba.ui.aribaweb.core.AWContainerElement;
import ariba.ui.aribaweb.core.AWComponent;
import ariba.ui.aribaweb.core.AWRequestContext;
import ariba.ui.aribaweb.core.AWTemplate;
import ariba.ui.aribaweb.core.AWElement;
import ariba.ui.aribaweb.core.AWBareString;
import ariba.ui.aribaweb.core.AWBinding;
import ariba.ui.aribaweb.core.AWHtmlTemplateParser;
import ariba.ui.aribaweb.core.AWComponentDefinition;
import ariba.ui.aribaweb.util.AWGenericException;
import ariba.ui.aribaweb.util.AWUtil;
import ariba.ui.aribaweb.util.Log;
import ariba.util.core.FastStringBuffer;
import ariba.util.core.MapUtil;
import ariba.util.core.StringUtil;
import ariba.util.core.Fmt;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import groovy.lang.GroovyClassLoader;

/**
* AWXGroovyTag tag delimits Groovy script meant to extend AW components on the
* server.
*/

public class AWXGroovyTag extends AWContainerElement implements AWComponentDefinition.ScriptClassProvider, AWHtmlTemplateParser.LiteralBody {
    private static final String SelfKey = "__AWXGroovyTag";
    protected Map _accessorNames = MapUtil.map();           
    static Map _classesByName = MapUtil.map();

    static {
        AWComponentDefinition.registerScriptProvider("groovy", new AWXGroovyTag());
    }

    public static class StatefulComponent extends AWComponent
    {
        public boolean isStateless ()
        {
            return false;
        }
    }

    public static void initialize ()
    {

    }
   
    // public Class componentSubclass (String name, AWTemplate template);

    public Class componentSubclass (String packageName, String className, String body, Class superclass)
    {
        String scName = (superclass != null)
                ? superclass.getName()
                : "ariba.ui.groovy.AWXGroovyTag.StatefulComponent";
        return groovyClassForBody(packageName, className, scName, body);
    }

    public Class componentSubclass(String name, AWTemplate template)
    {
        final FastStringBuffer buf = new FastStringBuffer();

        // Get <groovy> tag content
        AWUtil.iterate(template, new AWUtil.ElementIterator() {
            public Object process(AWElement e) {
                if (e instanceof AWXGroovyTag) {
                    buf.append(((AWXGroovyTag)e).scriptString());
                }
                return null; // keep looking
            }
        });
        // Generate code for expression bindings
    /* Disable groovy expression in favor of util.expr expressions...
        buf.append("\n// Expression Binding generated accessors ---- \n ");
        AWUtil.iterate(template, new AWUtil.ElementIterator() {
            public Object process(AWElement e) {
               if (e instanceof AWBindable) {
                    AWBindable reference = ((AWBindable)e);
                    String prefix = reference.tagName(); // componentDefinition().componentName().replace('.','_');
                    processBindings(prefix, reference.allBindings(), buf);
                }
                return null; // keep looking
            }
        });
    */

        String string = buf.toString();
        return groovyClassForBody("ariba.ui.demoshell.demo",
                                  name.replace('.', '_').replace('-', '_'),
                                  "ariba.ui.demoshell.AWXHTMLComponent",
                                   string);
    }

    protected void processBindings (String prefix, AWBinding[] bindings, FastStringBuffer buf)
    {
        int i = bindings.length;
        while (i-- > 0) {
            AWBinding binding = bindings[i];
            Log.aribaweb.debug("------- binding: %s", binding.bindingName());

            if (binding instanceof AWBinding.ExpressionBinding) {
                processExpressionBinding(prefix, (AWBinding.ExpressionBinding)binding, buf);
            }
        }
    }

    /*
        Patterns:
          $:expr
              if just \w[]. then can be lvalue (setter supported)
          $:=varName
              declare var name
          $:=expr
              anonymous varname expression
          $:foo=expr
              declare var name with initializer
     */
        // =var_name1
    private static Pattern VarDeclPattern = Pattern.compile("\\=(\\w+)\\s*$");
        // var_name1=expr
    private static Pattern VarDeclInitPattern = Pattern.compile("\\s*(\\w+)\\s*\\=(.+)$");
        // foo.bar[1]
    private static Pattern LValuePattern = Pattern.compile("([\\w|\\.|\\[|\\]]+)\\s*$");

    void processExpressionBinding (String prefix, AWBinding.ExpressionBinding binding, FastStringBuffer buf)
    {
        String exprString = binding.expressionString();

        // compute acceesor name (and de-dup)
        String key = null;

        String accessorString;
        Matcher m = VarDeclPattern.matcher(exprString);
        if (m.matches()) {
            key = m.group(1);
            accessorString = Fmt.S("def %s; // var decl\n", key);
        } else if ((m = VarDeclInitPattern.matcher(exprString)).matches()) {
            key = m.group(1);
            accessorString = Fmt.S("def %s; // var init\n", exprString);
        } else {
            // generate function name
            key = prefix + "_" + ((AWBinding)binding).name().string();
            key = uniqueName(key, _accessorNames);
            _accessorNames.put(key, key);

            // read accessor
            accessorString = Fmt.S("def %s() { %s }\n", key, exprString);

            // write accessor?
            if (LValuePattern.matcher(exprString).matches()) {
                accessorString += Fmt.S("def set%s(arg_a) { %s = arg_a; }\n",
                        StringUtil.capitalizeFirstChar(key), exprString);
            }
        }

        buf.append(accessorString);
        binding.setSubstituteBinding(AWBinding.fieldBinding(key, key, null));
    }

    private static Pattern ClassDeclPattern = Pattern.compile("\\s*class\\s+(\\w+)\\s+extends\\s+([\\w\\.]+)\\s*");
    private static Pattern ImportDeclPattern = Pattern.compile("(\\s*import\\s+[\\w\\.]+\\*?[\\s\\;]*)+");

    protected Class groovyClassForBody (String packageName, String name, String parentClassName, String bodyString)
    {
        final FastStringBuffer buf = new FastStringBuffer();
        String className = uniqueName(name, _classesByName);
        String classString;

        // support for scripts where we don't wrap it -- i.e. where script sets own parent class, imports, etc
        // and can include multiple classes in single file.
        Matcher m = ClassDeclPattern.matcher(bodyString);
        if (m.find()) {
            String theirName = m.group(1);
            String theirSuper = m.group(2);
            classString = m.replaceFirst(Fmt.S("\n\nclass %s extends %s ", className, theirSuper));
        } else {
            String extraImports = "";
            m = ImportDeclPattern.matcher(bodyString);
            if (m.find() && m.start() < 2) {
                extraImports = m.group(0);
                bodyString = m.replaceFirst("");
            }

            classString = Fmt.S("package %s\n%s%s\nclass %s extends %s {\n %s \n}",
                    packageName,
                    "import ariba.ui.aribaweb.core.*;import ariba.ui.widgets.*;import ariba.ui.table.*;import ariba.ui.outline.*;import ariba.util.core.*;",
                    extraImports, className, parentClassName, bodyString);
        }

        // use groovy class loader to load class as necessary...
        GroovyClassLoader gcl = AWGroovyLoader.gcl();

        Log.aribaweb.debug("--- Generating class: %s", className);
        // classString += "\n\n class C2 { def test () { return \"Yeah!\" }; } \n";

        Class cls;
        try {
            cls = gcl.parseClass(classString, className+".groovy");
        } catch (Exception e) {
            FastStringBuffer lineBuf = new FastStringBuffer();
            String[] lines = classString.split("\n");
            for (int i=0; i < lines.length; i++) {
                lineBuf.append(Integer.toString(i+1));
                lineBuf.append(": ");
                lineBuf.append(lines[i]);
                lineBuf.append("\n");
            }
            throw new AWGenericException(Fmt.S("Exception parsing groovy for class %s: %s\n%s", className,
                    e.getMessage(), lineBuf.toString()));
        }
        _classesByName.put(className, cls);
        return cls;
    }

    protected String uniqueName (String name, Map map)
    {
        int i = 0;
        String candidate = name;
        while (map.get(candidate) != null) {
            candidate = StringUtil.strcat(name, "_" + Integer.toString(i++));
        }
        return candidate;
    }

    public static AWXGroovyTag instanceInComponent (AWComponent component)
    {
        return (AWXGroovyTag) AWUtil.elementOfClass(component.template(), AWXGroovyTag.class);
    }

    public void renderResponse(AWRequestContext requestContext, AWComponent component)
    {
        // swallow our content
    }

    public String scriptString ()
    {
        AWElement content = contentElement();
        if (content instanceof AWBareString) {
            return ((AWBareString)content).string();
        }
        throw new AWGenericException("AWXGroovyTag with content that is not a BareString!");
    }
}
TOP

Related Classes of ariba.ui.groovy.AWXGroovyTag$StatefulComponent

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.