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

groovy.util.DelegatingScript Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2003-2014 the original author or authors.
 *
 * 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.
 */
package groovy.util;

import groovy.lang.Binding;
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);
 * 
* * @author Kohsuke Kawaguchi */ 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 { 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