Search in sources :

Example 6 with DelegatingMetaClass

use of groovy.lang.DelegatingMetaClass in project groovy-core by groovy.

the class MixinInMetaClass method mixinClassesToMetaClass.

public static void mixinClassesToMetaClass(MetaClass self, List<Class> categoryClasses) {
    final Class selfClass = self.getTheClass();
    if (self instanceof HandleMetaClass) {
        self = (MetaClass) ((HandleMetaClass) self).replaceDelegate();
    }
    if (!(self instanceof ExpandoMetaClass)) {
        if (self instanceof DelegatingMetaClass && ((DelegatingMetaClass) self).getAdaptee() instanceof ExpandoMetaClass) {
            self = ((DelegatingMetaClass) self).getAdaptee();
        } else {
            throw new GroovyRuntimeException("Can't mixin methods to meta class: " + self);
        }
    }
    ExpandoMetaClass mc = (ExpandoMetaClass) self;
    List<MetaMethod> arr = new ArrayList<MetaMethod>();
    for (Class categoryClass : categoryClasses) {
        final CachedClass cachedCategoryClass = ReflectionCache.getCachedClass(categoryClass);
        final MixinInMetaClass mixin = new MixinInMetaClass(mc, cachedCategoryClass);
        final MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(categoryClass);
        final List<MetaProperty> propList = metaClass.getProperties();
        for (MetaProperty prop : propList) if (self.getMetaProperty(prop.getName()) == null) {
            mc.registerBeanProperty(prop.getName(), new MixinInstanceMetaProperty(prop, mixin));
        }
        for (MetaProperty prop : cachedCategoryClass.getFields()) if (self.getMetaProperty(prop.getName()) == null) {
            mc.registerBeanProperty(prop.getName(), new MixinInstanceMetaProperty(prop, mixin));
        }
        for (MetaMethod method : metaClass.getMethods()) {
            final int mod = method.getModifiers();
            if (!Modifier.isPublic(mod))
                continue;
            if (method instanceof CachedMethod && ((CachedMethod) method).getCachedMethod().isSynthetic())
                continue;
            if (Modifier.isStatic(mod)) {
                if (method instanceof CachedMethod)
                    staticMethod(self, arr, (CachedMethod) method);
            } else if (method.getDeclaringClass().getTheClass() != Object.class || method.getName().equals("toString")) {
                // if (self.pickMethod(method.getName(), method.getNativeParameterTypes()) == null) {
                final MixinInstanceMetaMethod metaMethod = new MixinInstanceMetaMethod(method, mixin);
                arr.add(metaMethod);
            // }
            }
        }
    }
    for (Object res : arr) {
        final MetaMethod metaMethod = (MetaMethod) res;
        if (metaMethod.getDeclaringClass().isAssignableFrom(selfClass))
            mc.registerInstanceMethod(metaMethod);
        else {
            mc.registerSubclassInstanceMethod(metaMethod);
        }
    }
}
Also used : MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod) MetaMethod(groovy.lang.MetaMethod) NewInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod) HandleMetaClass(org.codehaus.groovy.runtime.HandleMetaClass) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) ArrayList(java.util.ArrayList) MetaClass(groovy.lang.MetaClass) ExpandoMetaClass(groovy.lang.ExpandoMetaClass) MixedInMetaClass(org.codehaus.groovy.runtime.metaclass.MixedInMetaClass) HandleMetaClass(org.codehaus.groovy.runtime.HandleMetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) MixinInstanceMetaProperty(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaProperty) MetaClass(groovy.lang.MetaClass) ExpandoMetaClass(groovy.lang.ExpandoMetaClass) MixedInMetaClass(org.codehaus.groovy.runtime.metaclass.MixedInMetaClass) HandleMetaClass(org.codehaus.groovy.runtime.HandleMetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) ExpandoMetaClass(groovy.lang.ExpandoMetaClass) MixinInstanceMetaProperty(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaProperty) MetaProperty(groovy.lang.MetaProperty) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod)

Example 7 with DelegatingMetaClass

use of groovy.lang.DelegatingMetaClass in project groovy-core by groovy.

the class GPathResult method setMetaClass.

/**
 * Replaces the MetaClass of this GPathResult.
 *
 * @param metaClass the new MetaClass
 */
@Override
public void setMetaClass(final MetaClass metaClass) {
    final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {

        @Override
        public Object getAttribute(final Object object, final String attribute) {
            return GPathResult.this.getProperty("@" + attribute);
        }

        @Override
        public void setAttribute(final Object object, final String attribute, final Object newValue) {
            GPathResult.this.setProperty("@" + attribute, newValue);
        }
    };
    super.setMetaClass(newMetaClass);
}
Also used : MetaClass(groovy.lang.MetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) GroovyObject(groovy.lang.GroovyObject) GString(groovy.lang.GString) DelegatingMetaClass(groovy.lang.DelegatingMetaClass)

Example 8 with DelegatingMetaClass

use of groovy.lang.DelegatingMetaClass in project groovy-core by groovy.

the class GroovyScriptEngineImpl method eval.

// package-privates
Object eval(Class scriptClass, final ScriptContext ctx) throws ScriptException {
    // Only initialize once.
    if (null == ctx.getAttribute("context", ScriptContext.ENGINE_SCOPE)) {
        // add context to bindings
        ctx.setAttribute("context", ctx, ScriptContext.ENGINE_SCOPE);
        // direct output to ctx.getWriter
        // If we're wrapping with a PrintWriter here,
        // enable autoFlush because otherwise it might not get done!
        final Writer writer = ctx.getWriter();
        ctx.setAttribute("out", (writer instanceof PrintWriter) ? writer : new PrintWriter(writer, true), ScriptContext.ENGINE_SCOPE);
    // Not going to do this after all (at least for now).
    // Scripts can use context.{reader, writer, errorWriter}.
    // That is a modern version of System.{in, out, err} or Console.{reader, writer}().
    // 
    // // New I/O names consistent with ScriptContext and java.io.Console.
    // 
    // ctx.setAttribute("writer", writer, ScriptContext.ENGINE_SCOPE);
    // 
    // // Direct errors to ctx.getErrorWriter
    // final Writer errorWriter = ctx.getErrorWriter();
    // ctx.setAttribute("errorWriter", (errorWriter instanceof PrintWriter) ?
    // errorWriter :
    // new PrintWriter(errorWriter),
    // ScriptContext.ENGINE_SCOPE);
    // 
    // // Get input from ctx.getReader
    // // We don't wrap with BufferedReader here because we expect that if
    // // the host wants that they do it.  Either way Groovy scripts will
    // // always have readLine because the GDK supplies it for Reader.
    // ctx.setAttribute("reader", ctx.getReader(), ScriptContext.ENGINE_SCOPE);
    }
    // Fix for GROOVY-3669: Can't use several times the same JSR-223 ScriptContext for differents groovy script
    if (ctx.getWriter() != null) {
        ctx.setAttribute("out", new PrintWriter(ctx.getWriter(), true), ScriptContext.ENGINE_SCOPE);
    }
    /*
         * We use the following Binding instance so that global variable lookup
         * will be done in the current ScriptContext instance.
         */
    Binding binding = new Binding(ctx.getBindings(ScriptContext.ENGINE_SCOPE)) {

        @Override
        public Object getVariable(String name) {
            synchronized (ctx) {
                int scope = ctx.getAttributesScope(name);
                if (scope != -1) {
                    return ctx.getAttribute(name, scope);
                }
            }
            throw new MissingPropertyException(name, getClass());
        }

        @Override
        public void setVariable(String name, Object value) {
            synchronized (ctx) {
                int scope = ctx.getAttributesScope(name);
                if (scope == -1) {
                    scope = ScriptContext.ENGINE_SCOPE;
                }
                ctx.setAttribute(name, value, scope);
            }
        }
    };
    try {
        // then simply return that class
        if (!Script.class.isAssignableFrom(scriptClass)) {
            return scriptClass;
        } else {
            // it's a script
            Script scriptObject = InvokerHelper.createScript(scriptClass, binding);
            // save all current closures into global closures map
            Method[] methods = scriptClass.getMethods();
            for (Method m : methods) {
                String name = m.getName();
                globalClosures.put(name, new MethodClosure(scriptObject, name));
            }
            MetaClass oldMetaClass = scriptObject.getMetaClass();
            /*
                * We override the MetaClass of this script object so that we can
                * forward calls to global closures (of previous or future "eval" calls)
                * This gives the illusion of working on the same "global" scope.
                */
            scriptObject.setMetaClass(new DelegatingMetaClass(oldMetaClass) {

                @Override
                public Object invokeMethod(Object object, String name, Object args) {
                    if (args == null) {
                        return invokeMethod(object, name, MetaClassHelper.EMPTY_ARRAY);
                    }
                    if (args instanceof Tuple) {
                        return invokeMethod(object, name, ((Tuple) args).toArray());
                    }
                    if (args instanceof Object[]) {
                        return invokeMethod(object, name, (Object[]) args);
                    } else {
                        return invokeMethod(object, name, new Object[] { args });
                    }
                }

                @Override
                public Object invokeMethod(Object object, String name, Object[] args) {
                    try {
                        return super.invokeMethod(object, name, args);
                    } catch (MissingMethodException mme) {
                        return callGlobal(name, args, ctx);
                    }
                }

                @Override
                public Object invokeStaticMethod(Object object, String name, Object[] args) {
                    try {
                        return super.invokeStaticMethod(object, name, args);
                    } catch (MissingMethodException mme) {
                        return callGlobal(name, args, ctx);
                    }
                }
            });
            return scriptObject.run();
        }
    } catch (Exception e) {
        throw new ScriptException(e);
    } finally {
        // Fix for GROOVY-3669: Can't use several times the same JSR-223 ScriptContext for different groovy script
        // Groovy's scripting engine implementation adds those two variables in the binding
        // but should clean up afterwards
        ctx.removeAttribute("context", ScriptContext.ENGINE_SCOPE);
        ctx.removeAttribute("out", ScriptContext.ENGINE_SCOPE);
    }
}
Also used : Binding(groovy.lang.Binding) Script(groovy.lang.Script) CompiledScript(javax.script.CompiledScript) MissingPropertyException(groovy.lang.MissingPropertyException) String(java.lang.String) Method(java.lang.reflect.Method) MethodClosure(org.codehaus.groovy.runtime.MethodClosure) MissingPropertyException(groovy.lang.MissingPropertyException) ScriptException(javax.script.ScriptException) MissingMethodException(groovy.lang.MissingMethodException) IOException(java.io.IOException) CompilationFailedException(org.codehaus.groovy.control.CompilationFailedException) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) ScriptException(javax.script.ScriptException) MissingMethodException(groovy.lang.MissingMethodException) MetaClass(groovy.lang.MetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) PrintWriter(java.io.PrintWriter) Writer(java.io.Writer) Tuple(groovy.lang.Tuple) PrintWriter(java.io.PrintWriter)

Example 9 with DelegatingMetaClass

use of groovy.lang.DelegatingMetaClass in project groovy-core by groovy.

the class Node method setMetaClass.

/**
 * Extension point for subclasses to override the metaclass. The default
 * one supports the property and @ attribute notations.
 *
 * @param metaClass the original metaclass
 * @param nodeClass the class whose metaclass we wish to override (this class or a subclass)
 */
protected static void setMetaClass(final MetaClass metaClass, Class nodeClass) {
    // TODO Is protected static a bit of a smell?
    // TODO perhaps set nodeClass to be Class<? extends Node>
    final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {

        @Override
        public Object getAttribute(final Object object, final String attribute) {
            Node n = (Node) object;
            return n.get("@" + attribute);
        }

        @Override
        public void setAttribute(final Object object, final String attribute, final Object newValue) {
            Node n = (Node) object;
            n.attributes().put(attribute, newValue);
        }

        @Override
        public Object getProperty(Object object, String property) {
            if (object instanceof Node) {
                Node n = (Node) object;
                return n.get(property);
            }
            return super.getProperty(object, property);
        }

        @Override
        public void setProperty(Object object, String property, Object newValue) {
            if (property.startsWith("@")) {
                setAttribute(object, property.substring(1), newValue);
                return;
            }
            delegate.setProperty(object, property, newValue);
        }
    };
    GroovySystem.getMetaClassRegistry().setMetaClass(nodeClass, newMetaClass);
}
Also used : MetaClass(groovy.lang.MetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass)

Example 10 with DelegatingMetaClass

use of groovy.lang.DelegatingMetaClass in project groovy-core by groovy.

the class NodeList method setMetaClass.

protected static void setMetaClass(final Class nodelistClass, final MetaClass metaClass) {
    final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {

        @Override
        public Object getAttribute(final Object object, final String attribute) {
            NodeList nl = (NodeList) object;
            Iterator it = nl.iterator();
            List result = new ArrayList();
            while (it.hasNext()) {
                Node node = (Node) it.next();
                result.add(node.attributes().get(attribute));
            }
            return result;
        }

        @Override
        public void setAttribute(final Object object, final String attribute, final Object newValue) {
            for (Object o : (NodeList) object) {
                Node node = (Node) o;
                node.attributes().put(attribute, newValue);
            }
        }

        @Override
        public Object getProperty(Object object, String property) {
            if (object instanceof NodeList) {
                NodeList nl = (NodeList) object;
                return nl.getAt(property);
            }
            return super.getProperty(object, property);
        }
    };
    GroovySystem.getMetaClassRegistry().setMetaClass(nodelistClass, newMetaClass);
}
Also used : MetaClass(groovy.lang.MetaClass) DelegatingMetaClass(groovy.lang.DelegatingMetaClass) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) DelegatingMetaClass(groovy.lang.DelegatingMetaClass)

Aggregations

DelegatingMetaClass (groovy.lang.DelegatingMetaClass)11 MetaClass (groovy.lang.MetaClass)11 ArrayList (java.util.ArrayList)4 Binding (groovy.lang.Binding)3 MissingMethodException (groovy.lang.MissingMethodException)3 MissingPropertyException (groovy.lang.MissingPropertyException)3 Script (groovy.lang.Script)3 Tuple (groovy.lang.Tuple)3 IOException (java.io.IOException)3 PrintWriter (java.io.PrintWriter)3 Method (java.lang.reflect.Method)3 CompiledScript (javax.script.CompiledScript)3 ScriptException (javax.script.ScriptException)3 CompilationFailedException (org.codehaus.groovy.control.CompilationFailedException)3 MethodClosure (org.codehaus.groovy.runtime.MethodClosure)3 ExpandoMetaClass (groovy.lang.ExpandoMetaClass)2 GString (groovy.lang.GString)2 GroovyObject (groovy.lang.GroovyObject)2 GroovyRuntimeException (groovy.lang.GroovyRuntimeException)2 MetaMethod (groovy.lang.MetaMethod)2