All Downloads are FREE. Search and download functionalities are using the official Maven repository.

groovy.util.DelegatingScript Maven / Gradle / Ivy

There is a newer version: 3.0.23
Show newest version
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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.
 */
package groovy.util;

import groovy.lang.Binding;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.lang.MissingMethodException;
import groovy.lang.MissingPropertyException;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;

/**
 * {@link Script} that performs method invocations and property access like {@link groovy.lang.Closure} does.
 *
 * 

* {@link DelegatingScript} is a convenient basis for loading a custom-defined DSL as a {@link Script}, then execute it. * The following sample code illustrates how to do it: * *

 * class MyDSL {
 *     public void foo(int x, int y, Closure z) { ... }
 *     public void setBar(String a) { ... }
 * }
 *
 * CompilerConfiguration cc = new CompilerConfiguration();
 * cc.setScriptBaseClass(DelegatingScript.class.getName());
 * GroovyShell sh = new GroovyShell(cl,new Binding(),cc);
 * DelegatingScript script = (DelegatingScript)sh.parse(new File("my.dsl"))
 * script.setDelegate(new MyDSL());
 * script.run();
 * 
* *

* my.dsl can look like this: * *

 * foo(1,2) {
 *     ....
 * }
 * bar = ...;
 * 
* *

* {@link DelegatingScript} does this by delegating property access and method invocation to the delegate object. * *

* More formally speaking, given the following script: * *

 * a = 1;
 * b(2);
 * 
* *

* Using {@link DelegatingScript} as the base class, the code will run as: * *

 * delegate.a = 1;
 * delegate.b(2);
 * 
* * ... whereas in plain {@link Script}, this will be run as: * *
 * binding.setProperty("a",1);
 * ((Closure)binding.getProperty("b")).call(2);
 * 
*/ public abstract class DelegatingScript extends Script { private Object delegate; private MetaClass metaClass; protected DelegatingScript() { super(); } protected DelegatingScript(Binding binding) { super(binding); } /** * Sets the delegation target. */ public void setDelegate(Object delegate) { this.delegate = delegate; this.metaClass = InvokerHelper.getMetaClass(delegate.getClass()); } @Override public Object invokeMethod(String name, Object args) { try { if (delegate instanceof GroovyObject) { return ((GroovyObject) delegate).invokeMethod(name, args); } return metaClass.invokeMethod(delegate, name, args); } catch (MissingMethodException mme) { return super.invokeMethod(name, args); } } @Override public Object getProperty(String property) { try { return metaClass.getProperty(delegate,property); } catch (MissingPropertyException e) { return super.getProperty(property); } } @Override public void setProperty(String property, Object newValue) { try { metaClass.setProperty(delegate,property,newValue); } catch (MissingPropertyException e) { super.setProperty(property,newValue); } } public Object getDelegate() { return delegate; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy