@SuppressWarnings("rawtypes") private void cleanup(GantResult result, GantBinding binding) { if (result != null) { Class cls = GantMetaClass.class; try { Field methodsInvoked = cls.getDeclaredField("methodsInvoked"); methodsInvoked.setAccessible(true); Set methodsInvokedSet = (Set) methodsInvoked.get(cls); if (methodsInvokedSet != null) { methodsInvokedSet.clear(); } } catch (NoSuchFieldException e) { // ignore } catch (IllegalAccessException e) { // ignore } } System.setIn(originalIn); System.setOut(originalOut); GrailsPluginUtils.clearCaches(); Map variables = binding.getVariables(); Object pluginsSettingsObject = variables.get("pluginsSettings"); if (pluginsSettingsObject instanceof PluginBuildSettings) { ((PluginBuildSettings) pluginsSettingsObject).clearCache(); } GroovySystem.getMetaClassRegistry().removeMetaClass(GantBinding.class); GroovySystem.getMetaClassRegistry().removeMetaClass(Gant.class); }
private MetaClass getMetaClass() { if (bean instanceof GroovyObject) { return ((GroovyObject) bean).getMetaClass(); } else { return GroovySystem.getMetaClassRegistry().getMetaClass(bean.getClass()); } }
// package-level visibility for testing purposes (just usage/errors at this stage) // TODO: should we have an 'err' printstream too for ParseException? static void processArgs(String[] args, final PrintStream out) { Options options = buildOptions(); try { CommandLine cmd = parseCommandLine(options, args); if (cmd.hasOption('h')) { printHelp(out, options); } else if (cmd.hasOption('v')) { String version = GroovySystem.getVersion(); out.println( "Groovy Version: " + version + " JVM: " + System.getProperty("java.version") + " Vendor: " + System.getProperty("java.vm.vendor") + " OS: " + System.getProperty("os.name")); } else { // If we fail, then exit with an error so scripting frameworks can catch it // TODO: pass printstream(s) down through process if (!process(cmd)) { System.exit(1); } } } catch (ParseException pe) { out.println("error: " + pe.getMessage()); printHelp(out, options); } }
@SuppressWarnings("rawtypes") public static MetaClass getExpandoMetaClass(Class clazz) { MetaClassRegistry registry = GroovySystem.getMetaClassRegistry(); Assert.isTrue( registry.getMetaClassCreationHandler() instanceof ExpandoMetaClassCreationHandle, "Grails requires an instance of [ExpandoMetaClassCreationHandle] to be set in Groovy's MetaClassRegistry! (current is : " + registry.getMetaClassCreationHandler() + ")"); MetaClass mc = registry.getMetaClass(clazz); AdaptingMetaClass adapter = null; if (mc instanceof AdaptingMetaClass) { adapter = (AdaptingMetaClass) mc; mc = ((AdaptingMetaClass) mc).getAdaptee(); } if (!(mc instanceof ExpandoMetaClass)) { // removes cached version registry.removeMetaClass(clazz); mc = registry.getMetaClass(clazz); if (adapter != null) { adapter.setAdaptee(mc); } } Assert.isTrue( mc instanceof ExpandoMetaClass, "BUG! Method must return an instance of [ExpandoMetaClass]!"); return mc; }
/** * Associations both sides of any bidirectional relationships found in the object and source map * to bind * * @param object The object * @param source The source map * @param domainClass The DomainClass for the object */ public static void assignBidirectionalAssociations( Object object, Map source, GrailsDomainClass domainClass) { if (source == null) { return; } for (Object key : source.keySet()) { String propertyName = key.toString(); if (propertyName.indexOf('.') > -1) { propertyName = propertyName.substring(0, propertyName.indexOf('.')); } if (domainClass.hasPersistentProperty(propertyName)) { GrailsDomainClassProperty prop = domainClass.getPropertyByName(propertyName); if (prop != null && prop.isOneToOne() && prop.isBidirectional()) { Object val = source.get(key); GrailsDomainClassProperty otherSide = prop.getOtherSide(); if (val != null && otherSide != null) { MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(val.getClass()); try { mc.setProperty(val, otherSide.getName(), object); } catch (Exception e) { // ignore } } } } } }
/** * Ensures the meta class is correct for a given class * * @param target The GroovyObject * @param persistentClass The persistent class */ public static void ensureCorrectGroovyMetaClass(Object target, Class<?> persistentClass) { if (target instanceof GroovyObject) { GroovyObject go = ((GroovyObject) target); if (!go.getMetaClass().getTheClass().equals(persistentClass)) { go.setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(persistentClass)); } } }
public static MetaClassRegistryCleaner createAndRegister() { MetaClassRegistry metaClassRegistry = GroovySystem.getMetaClassRegistry(); MetaClassRegistryChangeEventListener[] listeners = metaClassRegistry.getMetaClassRegistryChangeEventListeners(); boolean registered = false; for (MetaClassRegistryChangeEventListener listener : listeners) { if (listener == INSTANCE) { registered = true; break; } } if (!registered) { GroovySystem.getMetaClassRegistry().addMetaClassRegistryChangeEventListener(INSTANCE); } return INSTANCE; }
/** * The reference instance is used to get configured property values. * * @return BeanWrapper instance that holds reference */ public BeanWrapper getReference() { Object obj = this.reference.getWrappedInstance(); if (obj instanceof GroovyObject) { ((GroovyObject) obj) .setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(getClazz())); } return this.reference; }
private MetaClass getMetaClass(Object proxy) { MetaClass mc = metaClass; if (mc == null) { mc = ((MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry()).getMetaClass(proxy); metaClass = mc; } return mc; }
static SpecifiedVersion getWorkspaceCompilerLevel() { String groovyVersion = GroovySystem.getVersion(); // convert from major.minor.micro to major.minor int dotIndex = groovyVersion.lastIndexOf('.'); if (dotIndex > 0) { groovyVersion = groovyVersion.substring(0, dotIndex); } return SpecifiedVersion.findVersionFromString(groovyVersion); }
public static int selectConstructorAndTransformArguments( Object[] arguments, int numberOfConstructors, Class which) throws Throwable { MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(which); try { return metaClass.selectConstructorAndTransformArguments(numberOfConstructors, arguments); } catch (GroovyRuntimeException gre) { throw unwrap(gre); } }
private void addAssociationToTarget(String name, Object target, Object obj) { if (obj == null) { return; } MetaClassRegistry reg = GroovySystem.getMetaClassRegistry(); MetaClass mc = reg.getMetaClass(target.getClass()); final String addMethodName = "addTo" + GrailsNameUtils.getClassNameRepresentation(name); mc.invokeMethod(target, addMethodName, obj); }
/** * Increments the entities version number in order to force an update * * @param target The target entity */ public static void incrementVersion(Object target) { MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(target.getClass()); if (metaClass.hasProperty(target, GormProperties.VERSION) != null) { Object version = metaClass.getProperty(target, GormProperties.VERSION); if (version instanceof Long) { Long newVersion = (Long) version + 1; metaClass.setProperty(target, GormProperties.VERSION, newVersion); } } }
public synchronized void clean() { try { cleaning = true; MetaClassRegistryImpl registry = (MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry(); cleanMetaClassOfClass(registry); cleanMetaClassOfInstance(registry); } finally { cleaning = false; } }
private static GroovyClassLoader getGroovyClassLoader() { GroovySystem.getMetaClassRegistry() .setMetaClassCreationHandle(new ExpandoMetaClassCreationHandle()); CompilerConfiguration config = new CompilerConfiguration(); config.setDebug(true); config.setVerbose(true); ClassLoader parent = ClassLoader.getSystemClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); loader.setShouldRecompile(true); return loader; }
private static ScriptEngine getGroovyEngine() { synchronized (Groovyness.class) { if (groovyEngine == null) { GroovySystem.getMetaClassRegistry() .setMetaClassCreationHandle(new ExpandoMetaClassCreationHandle()); ScriptEngineManager manager = new ScriptEngineManager(getGroovyClassLoader()); groovyEngine = manager.getEngineByName("groovy"); } return groovyEngine; } }
/** * Locates the name of a property for the given value on the target object using Groovy's meta * APIs. Note that this method uses the reference so the incorrect result could be returned for * two properties that refer to the same reference. Use with caution. * * @param target The target * @param obj The property value * @return The property name or null */ public static String findPropertyNameForValue(Object target, Object obj) { MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(target.getClass()); List<MetaProperty> metaProperties = mc.getProperties(); for (MetaProperty metaProperty : metaProperties) { if (isAssignableOrConvertibleFrom(metaProperty.getType(), obj.getClass())) { Object val = metaProperty.getProperty(target); if (val != null && val.equals(obj)) { return metaProperty.getName(); } } } return null; }
private Object autoInstantiateDomainInstance(Class<?> type) { Object created = null; try { MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(type); if (mc != null) { created = mc.invokeStaticMethod(type, CreateDynamicMethod.METHOD_NAME, new Object[0]); } } catch (MissingMethodException mme) { LOG.warn("Unable to auto-create type, 'create' method not found"); } catch (GroovyRuntimeException gre) { LOG.warn("Unable to auto-create type, Groovy Runtime error: " + gre.getMessage(), gre); } return created; }
public void enableUaa() { try { Class<?> uaaClass = BaseSettingsApi.class .getClassLoader() .loadClass("org.codehaus.groovy.grails.cli.support.UaaEnabler"); Object instance = uaaClass .getConstructor(new Class[] {BuildSettings.class, PluginBuildSettings.class}) .newInstance(buildSettings, pluginSettings); MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(uaaClass); metaClass.invokeMethod(instance, "enable", new Object[] {isInteractive}); } catch (Exception e) { // UAA not present, ignore } }
@SuppressWarnings("unchecked") private void initialize(Class<?> domainClazz, boolean failOnError, List failOnErrorPackages) { domainMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(domainClazz); dateCreatedProperty = domainMetaClass.getMetaProperty(GrailsDomainClassProperty.DATE_CREATED); lastUpdatedProperty = domainMetaClass.getMetaProperty(GrailsDomainClassProperty.LAST_UPDATED); if (dateCreatedProperty != null || lastUpdatedProperty != null) { Mapping m = GrailsDomainBinder.getMapping(domainClazz); shouldTimestamp = (m != null && !m.isAutoTimestamp()) ? false : true; } saveOrUpdateCaller = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.ONLOAD_SAVE); beforeInsertCaller = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.BEFORE_INSERT_EVENT); preLoadEventCaller = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.ONLOAD_EVENT); if (preLoadEventCaller == null) { preLoadEventCaller = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.BEFORE_LOAD_EVENT); } postLoadEventListener = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.AFTER_LOAD_EVENT); postInsertEventListener = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.AFTER_INSERT_EVENT); postUpdateEventListener = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.AFTER_UPDATE_EVENT); postDeleteEventListener = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.AFTER_DELETE_EVENT); preDeleteEventListener = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.BEFORE_DELETE_EVENT); preUpdateEventListener = buildCaller(domainClazz, ClosureEventTriggeringInterceptor.BEFORE_UPDATE_EVENT); if (failOnErrorPackages.size() > 0) { failOnErrorEnabled = GrailsClassUtils.isClassBelowPackage(domainClazz, failOnErrorPackages); } else { failOnErrorEnabled = failOnError; } validateParams = new HashMap(); validateParams.put(ValidatePersistentMethod.ARGUMENT_DEEP_VALIDATE, Boolean.FALSE); errorsProperty = domainMetaClass.getMetaProperty(AbstractDynamicPersistentMethod.ERRORS_PROPERTY); validateMethod = domainMetaClass.getMetaMethod( ValidatePersistentMethod.METHOD_SIGNATURE, new Object[] {Map.class}); }
@Override protected void createCriteriaInstance() { { if (TransactionSynchronizationManager.hasResource(sessionFactory)) { participate = true; hibernateSession = ((SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory)) .getSession(); } else { hibernateSession = sessionFactory.openSession(); } criteria = hibernateSession.createCriteria(targetClass); cacheCriteriaMapping(); criteriaMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(criteria.getClass()); } }
@SuppressWarnings("unchecked") private Map resolveConstrainedProperties(Object object, GrailsDomainClass dc) { Map constrainedProperties = null; if (dc != null) { constrainedProperties = dc.getConstrainedProperties(); } else { // is this dead code? , didn't remove in case it's used somewhere MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(object.getClass()); MetaProperty metaProp = mc.getMetaProperty(CONSTRAINTS_PROPERTY); if (metaProp != null) { Object constrainedPropsObj = getMetaPropertyValue(metaProp, object); if (constrainedPropsObj instanceof Map) { constrainedProperties = (Map) constrainedPropsObj; } } } return constrainedProperties; }
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); } } }
private void removeBeanDefinition(BeanDefinitionRegistry registry, String beanName) { MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(registry.getClass()); if (mc.respondsTo(registry, "removeBeanDefinition").size() > 0) { mc.invokeMethod(registry, "removeBeanDefinition", new Object[] {beanName}); } }
/** * A Groovy-based reader for Spring bean definitions: like a Groovy builder, but more of a DSL for * Spring configuration. * * <p>This bean definition reader also understands XML bean definition files, allowing for seamless * mixing and matching with Groovy bean definition files. * * <p>Typically applied to a {@link * org.springframework.beans.factory.support.DefaultListableBeanFactory} or a {@link * org.springframework.context.support.GenericApplicationContext}, but can be used against any * {@link BeanDefinitionRegistry} implementation. * * <h3>Example Syntax</h3> * * <pre class="code"> * import org.hibernate.SessionFactory * import org.apache.commons.dbcp.BasicDataSource * * def reader = new GroovyBeanDefinitionReader(myApplicationContext) * reader.beans { * dataSource(BasicDataSource) { // <--- invokeMethod * driverClassName = "org.hsqldb.jdbcDriver" * url = "jdbc:hsqldb:mem:grailsDB" * username = "******" // <-- setProperty * password = "" * settings = [mynew:"setting"] * } * sessionFactory(SessionFactory) { * dataSource = dataSource // <-- getProperty for retrieving references * } * myService(MyService) { * nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean * dataSource = dataSource * } * } * }</pre> * * <p>You can also load resources containing beans defined in a Groovy script using either the * {@link #loadBeanDefinitions(Resource...)} or {@link #loadBeanDefinitions(String...)} method, with * a script looking similar to the following. * * <pre class="code"> * import org.hibernate.SessionFactory * import org.apache.commons.dbcp.BasicDataSource * * beans { * dataSource(BasicDataSource) { * driverClassName = "org.hsqldb.jdbcDriver" * url = "jdbc:hsqldb:mem:grailsDB" * username = "******" * password = "" * settings = [mynew:"setting"] * } * sessionFactory(SessionFactory) { * dataSource = dataSource * } * myService(MyService) { * nestedBean = { AnotherBean bean -> * dataSource = dataSource * } * } * }</pre> * * @author Jeff Brown * @author Graeme Rocher * @author Juergen Hoeller * @author Sam Brannen * @since 4.0 * @see BeanDefinitionRegistry * @see org.springframework.beans.factory.support.DefaultListableBeanFactory * @see org.springframework.context.support.GenericApplicationContext * @see org.springframework.context.support.GenericGroovyApplicationContext */ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader implements GroovyObject { /** * Standard {@code XmlBeanDefinitionReader} created with default settings for loading bean * definitions from XML files. */ private final XmlBeanDefinitionReader standardXmlBeanDefinitionReader; /** * Groovy DSL {@code XmlBeanDefinitionReader} for loading bean definitions via the Groovy DSL, * typically configured with XML validation disabled. */ private final XmlBeanDefinitionReader groovyDslXmlBeanDefinitionReader; private final Map<String, String> namespaces = new HashMap<>(); private final Map<String, DeferredProperty> deferredProperties = new HashMap<>(); private MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(getClass()); private Binding binding; private GroovyBeanDefinitionWrapper currentBeanDefinition; /** * Create a new {@code GroovyBeanDefinitionReader} for the given {@link BeanDefinitionRegistry}. * * @param registry the {@code BeanDefinitionRegistry} to load bean definitions into */ public GroovyBeanDefinitionReader(BeanDefinitionRegistry registry) { super(registry); this.standardXmlBeanDefinitionReader = new XmlBeanDefinitionReader(registry); this.groovyDslXmlBeanDefinitionReader = new XmlBeanDefinitionReader(registry); this.groovyDslXmlBeanDefinitionReader.setValidating(false); } /** * Create a new {@code GroovyBeanDefinitionReader} based on the given {@link * XmlBeanDefinitionReader}, loading bean definitions into its {@code BeanDefinitionRegistry} and * delegating Groovy DSL loading to it. * * <p>The supplied {@code XmlBeanDefinitionReader} should typically be pre-configured with XML * validation disabled. * * @param xmlBeanDefinitionReader the {@code XmlBeanDefinitionReader} to derive the registry from * and to delegate Groovy DSL loading to */ public GroovyBeanDefinitionReader(XmlBeanDefinitionReader xmlBeanDefinitionReader) { super(xmlBeanDefinitionReader.getRegistry()); this.standardXmlBeanDefinitionReader = new XmlBeanDefinitionReader(xmlBeanDefinitionReader.getRegistry()); this.groovyDslXmlBeanDefinitionReader = xmlBeanDefinitionReader; } public void setMetaClass(MetaClass metaClass) { this.metaClass = metaClass; } public MetaClass getMetaClass() { return this.metaClass; } /** * Set the binding, i.e. the Groovy variables available in the scope of a {@code * GroovyBeanDefinitionReader} closure. */ public void setBinding(Binding binding) { this.binding = binding; } /** Return a specified binding for Groovy variables, if any. */ public Binding getBinding() { return this.binding; } // TRADITIONAL BEAN DEFINITION READER METHODS /** * Load bean definitions from the specified Groovy script or XML file. * * <p>Note that {@code ".xml"} files will be parsed as XML content; all other kinds of resources * will be parsed as Groovy scripts. * * @param resource the resource descriptor for the Groovy script or XML file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */ public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); } /** * Load bean definitions from the specified Groovy script or XML file. * * <p>Note that {@code ".xml"} files will be parsed as XML content; all other kinds of resources * will be parsed as Groovy scripts. * * @param encodedResource the resource descriptor for the Groovy script or XML file, allowing * specification of an encoding to use for parsing the file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */ public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { // Check for XML files and redirect them to the "standard" XmlBeanDefinitionReader String filename = encodedResource.getResource().getFilename(); if (StringUtils.endsWithIgnoreCase(filename, ".xml")) { return this.standardXmlBeanDefinitionReader.loadBeanDefinitions(encodedResource); } Closure beans = new Closure(this) { public Object call(Object[] args) { invokeBeanDefiningClosure((Closure) args[0]); return null; } }; Binding binding = new Binding() { @Override public void setVariable(String name, Object value) { if (currentBeanDefinition != null) { applyPropertyToBeanDefinition(name, value); } else { super.setVariable(name, value); } } }; binding.setVariable("beans", beans); int countBefore = getRegistry().getBeanDefinitionCount(); try { GroovyShell shell = new GroovyShell(getResourceLoader().getClassLoader(), binding); shell.evaluate(encodedResource.getReader(), "beans"); } catch (Throwable ex) { throw new BeanDefinitionParsingException( new Problem( "Error evaluating Groovy script: " + ex.getMessage(), new Location(encodedResource.getResource()), null, ex)); } return getRegistry().getBeanDefinitionCount() - countBefore; } // METHODS FOR CONSUMPTION IN A GROOVY CLOSURE /** * Defines a set of beans for the given block or closure. * * @param closure the block or closure * @return this {@code GroovyBeanDefinitionReader} instance */ public GroovyBeanDefinitionReader beans(Closure closure) { return invokeBeanDefiningClosure(closure); } /** * Define an inner bean definition. * * @param type the bean type * @return the bean definition */ public GenericBeanDefinition bean(Class<?> type) { GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(type); return beanDefinition; } /** * Define an inner bean definition. * * @param type the bean type * @param args the constructors arguments and closure configurer * @return the bean definition */ public AbstractBeanDefinition bean(Class<?> type, Object... args) { GroovyBeanDefinitionWrapper current = this.currentBeanDefinition; try { Closure callable = null; Collection constructorArgs = null; if (!ObjectUtils.isEmpty(args)) { int index = args.length; Object lastArg = args[index - 1]; if (lastArg instanceof Closure) { callable = (Closure) lastArg; index--; } if (index > -1) { constructorArgs = resolveConstructorArguments(args, 0, index); } } this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(null, type, constructorArgs); if (callable != null) { callable.call(this.currentBeanDefinition); } return this.currentBeanDefinition.getBeanDefinition(); } finally { this.currentBeanDefinition = current; } } /** * Define a Spring XML namespace definition to use. * * @param definition the namespace definition */ public void xmlns(Map<String, String> definition) { if (!definition.isEmpty()) { for (Map.Entry<String, String> entry : definition.entrySet()) { String namespace = entry.getKey(); String uri = entry.getValue(); if (uri == null) { throw new IllegalArgumentException("Namespace definition must supply a non-null URI"); } NamespaceHandler namespaceHandler = this.groovyDslXmlBeanDefinitionReader.getNamespaceHandlerResolver().resolve(uri); if (namespaceHandler == null) { throw new BeanDefinitionParsingException( new Problem( "No namespace handler found for URI: " + uri, new Location(new DescriptiveResource(("Groovy"))))); } this.namespaces.put(namespace, uri); } } } /** * Import Spring bean definitions from either XML or Groovy sources into the current bean builder * instance. * * @param resourcePattern the resource pattern */ public void importBeans(String resourcePattern) throws IOException { loadBeanDefinitions(resourcePattern); } // INTERNAL HANDLING OF GROOVY CLOSURES AND PROPERTIES /** * This method overrides method invocation to create beans for each method name that takes a class * argument. */ public Object invokeMethod(String name, Object arg) { Object[] args = (Object[]) arg; if ("beans".equals(name) && args.length == 1 && args[0] instanceof Closure) { return beans((Closure) args[0]); } else if ("ref".equals(name)) { String refName; if (args[0] == null) throw new IllegalArgumentException( "Argument to ref() is not a valid bean or was not found"); if (args[0] instanceof RuntimeBeanReference) { refName = ((RuntimeBeanReference) args[0]).getBeanName(); } else { refName = args[0].toString(); } boolean parentRef = false; if (args.length > 1) { if (args[1] instanceof Boolean) { parentRef = (Boolean) args[1]; } } return new RuntimeBeanReference(refName, parentRef); } else if (this.namespaces.containsKey(name) && args.length > 0 && args[0] instanceof Closure) { GroovyDynamicElementReader reader = createDynamicElementReader(name); reader.invokeMethod("doCall", args); } else if (args.length > 0 && args[0] instanceof Closure) { // abstract bean definition return invokeBeanDefiningMethod(name, args); } else if (args.length > 0 && (args[0] instanceof Class || args[0] instanceof RuntimeBeanReference || args[0] instanceof Map)) { return invokeBeanDefiningMethod(name, args); } else if (args.length > 1 && args[args.length - 1] instanceof Closure) { return invokeBeanDefiningMethod(name, args); } MetaClass mc = DefaultGroovyMethods.getMetaClass(getRegistry()); if (!mc.respondsTo(getRegistry(), name, args).isEmpty()) { return mc.invokeMethod(getRegistry(), name, args); } return this; } private boolean addDeferredProperty(String property, Object newValue) { if (newValue instanceof List) { this.deferredProperties.put( this.currentBeanDefinition.getBeanName() + '.' + property, new DeferredProperty(this.currentBeanDefinition, property, newValue)); return true; } else if (newValue instanceof Map) { this.deferredProperties.put( this.currentBeanDefinition.getBeanName() + '.' + property, new DeferredProperty(this.currentBeanDefinition, property, newValue)); return true; } return false; } private void finalizeDeferredProperties() { for (DeferredProperty dp : this.deferredProperties.values()) { if (dp.value instanceof List) { dp.value = manageListIfNecessary((List) dp.value); } else if (dp.value instanceof Map) { dp.value = manageMapIfNecessary((Map) dp.value); } dp.apply(); } this.deferredProperties.clear(); } /** * When a method argument is only a closure it is a set of bean definitions. * * @param callable the closure argument * @return this {@code GroovyBeanDefinitionReader} instance */ protected GroovyBeanDefinitionReader invokeBeanDefiningClosure(Closure callable) { callable.setDelegate(this); callable.call(); finalizeDeferredProperties(); return this; } /** * This method is called when a bean definition node is called. * * @param beanName the name of the bean to define * @param args the arguments to the bean. The first argument is the class name, the last argument * is sometimes a closure. All the arguments in between are constructor arguments. * @return the bean definition wrapper */ private GroovyBeanDefinitionWrapper invokeBeanDefiningMethod(String beanName, Object[] args) { boolean hasClosureArgument = (args[args.length - 1] instanceof Closure); if (args[0] instanceof Class) { Class<?> beanClass = (Class<?>) args[0]; if (args.length >= 1) { if (hasClosureArgument) { if (args.length - 1 != 1) { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper( beanName, beanClass, resolveConstructorArguments(args, 1, args.length - 1)); } else { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, beanClass); } } else { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper( beanName, beanClass, resolveConstructorArguments(args, 1, args.length)); } } } else if (args[0] instanceof RuntimeBeanReference) { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName); this.currentBeanDefinition .getBeanDefinition() .setFactoryBeanName(((RuntimeBeanReference) args[0]).getBeanName()); } else if (args[0] instanceof Map) { // named constructor arguments if (args.length > 1 && args[1] instanceof Class) { List constructorArgs = resolveConstructorArguments( args, 2, hasClosureArgument ? args.length - 1 : args.length); this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class) args[1], constructorArgs); Map namedArgs = (Map) args[0]; for (Object o : namedArgs.keySet()) { String propName = (String) o; setProperty(propName, namedArgs.get(propName)); } } // factory method syntax else { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName); // First arg is the map containing factoryBean : factoryMethod Map.Entry factoryBeanEntry = (Map.Entry) ((Map) args[0]).entrySet().iterator().next(); // If we have a closure body, that will be the last argument. // In between are the constructor args int constructorArgsTest = hasClosureArgument ? 2 : 1; // If we have more than this number of args, we have constructor args if (args.length > constructorArgsTest) { // factory-method requires args int endOfConstructArgs = (hasClosureArgument ? args.length - 1 : args.length); this.currentBeanDefinition = new GroovyBeanDefinitionWrapper( beanName, null, resolveConstructorArguments(args, 1, endOfConstructArgs)); } else { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName); } this.currentBeanDefinition .getBeanDefinition() .setFactoryBeanName(factoryBeanEntry.getKey().toString()); this.currentBeanDefinition .getBeanDefinition() .setFactoryMethodName(factoryBeanEntry.getValue().toString()); } } else if (args[0] instanceof Closure) { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName); this.currentBeanDefinition.getBeanDefinition().setAbstract(true); } else { List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length - 1 : args.length); currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs); } if (hasClosureArgument) { Closure callable = (Closure) args[args.length - 1]; callable.setDelegate(this); callable.setResolveStrategy(Closure.DELEGATE_FIRST); callable.call(new Object[] {currentBeanDefinition}); } GroovyBeanDefinitionWrapper beanDefinition = currentBeanDefinition; this.currentBeanDefinition = null; beanDefinition .getBeanDefinition() .setAttribute(GroovyBeanDefinitionWrapper.class.getName(), beanDefinition); getRegistry().registerBeanDefinition(beanName, beanDefinition.getBeanDefinition()); return beanDefinition; } protected List<Object> resolveConstructorArguments(Object[] args, int start, int end) { Object[] constructorArgs = Arrays.copyOfRange(args, start, end); for (int i = 0; i < constructorArgs.length; i++) { if (constructorArgs[i] instanceof GString) { constructorArgs[i] = constructorArgs[i].toString(); } else if (constructorArgs[i] instanceof List) { constructorArgs[i] = manageListIfNecessary((List) constructorArgs[i]); } else if (constructorArgs[i] instanceof Map) { constructorArgs[i] = manageMapIfNecessary((Map) constructorArgs[i]); } } return Arrays.asList(constructorArgs); } /** * Checks whether there are any {@link RuntimeBeanReference}s inside the {@link Map} and converts * it to a {@link ManagedMap} if necessary. * * @param map the original Map * @return either the original map or a managed copy of it */ private Object manageMapIfNecessary(Map<?, ?> map) { boolean containsRuntimeRefs = false; for (Object element : map.values()) { if (element instanceof RuntimeBeanReference) { containsRuntimeRefs = true; break; } } if (containsRuntimeRefs) { Map<Object, Object> managedMap = new ManagedMap<>(); managedMap.putAll(map); return managedMap; } return map; } /** * Checks whether there are any {@link RuntimeBeanReference}s inside the {@link List} and converts * it to a {@link ManagedList} if necessary. * * @param list the original List * @return either the original list or a managed copy of it */ private Object manageListIfNecessary(List<?> list) { boolean containsRuntimeRefs = false; for (Object element : list) { if (element instanceof RuntimeBeanReference) { containsRuntimeRefs = true; break; } } if (containsRuntimeRefs) { List<Object> managedList = new ManagedList<>(); managedList.addAll(list); return managedList; } return list; } /** * This method overrides property setting in the scope of the {@code GroovyBeanDefinitionReader} * to set properties on the current bean definition. */ public void setProperty(String name, Object value) { if (this.currentBeanDefinition != null) { applyPropertyToBeanDefinition(name, value); } } protected void applyPropertyToBeanDefinition(String name, Object value) { if (value instanceof GString) { value = value.toString(); } if (addDeferredProperty(name, value)) { return; } else if (value instanceof Closure) { GroovyBeanDefinitionWrapper current = this.currentBeanDefinition; try { Closure callable = (Closure) value; Class<?> parameterType = callable.getParameterTypes()[0]; if (Object.class == parameterType) { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(""); callable.call(this.currentBeanDefinition); } else { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(null, parameterType); callable.call((Object) null); } value = this.currentBeanDefinition.getBeanDefinition(); } finally { this.currentBeanDefinition = current; } } this.currentBeanDefinition.addProperty(name, value); } /** * This method overrides property retrieval in the scope of the {@code GroovyBeanDefinitionReader} * to either: * * <ul> * <li>Retrieve a variable from the bean builder's binding if it exists * <li>Retrieve a RuntimeBeanReference for a specific bean if it exists * <li>Otherwise just delegate to MetaClass.getProperty which will resolve properties from the * {@code GroovyBeanDefinitionReader} itself * </ul> */ public Object getProperty(String name) { Binding binding = getBinding(); if (binding != null && binding.hasVariable(name)) { return binding.getVariable(name); } else { if (this.namespaces.containsKey(name)) { return createDynamicElementReader(name); } if (getRegistry().containsBeanDefinition(name)) { GroovyBeanDefinitionWrapper beanDefinition = (GroovyBeanDefinitionWrapper) getRegistry() .getBeanDefinition(name) .getAttribute(GroovyBeanDefinitionWrapper.class.getName()); if (beanDefinition != null) { return new GroovyRuntimeBeanReference(name, beanDefinition, false); } else { return new RuntimeBeanReference(name, false); } } // This is to deal with the case where the property setter is the last // statement in a closure (hence the return value) else if (this.currentBeanDefinition != null) { MutablePropertyValues pvs = this.currentBeanDefinition.getBeanDefinition().getPropertyValues(); if (pvs.contains(name)) { return pvs.get(name); } else { DeferredProperty dp = this.deferredProperties.get(this.currentBeanDefinition.getBeanName() + name); if (dp != null) { return dp.value; } else { return getMetaClass().getProperty(this, name); } } } else { return getMetaClass().getProperty(this, name); } } } private GroovyDynamicElementReader createDynamicElementReader(String namespace) { XmlReaderContext readerContext = this.groovyDslXmlBeanDefinitionReader.createReaderContext( new DescriptiveResource("Groovy")); BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); boolean decorating = (this.currentBeanDefinition != null); if (!decorating) { this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(namespace); } return new GroovyDynamicElementReader( namespace, this.namespaces, delegate, this.currentBeanDefinition, decorating) { @Override protected void afterInvocation() { if (!this.decorating) { currentBeanDefinition = null; } } }; } /** * This class is used to defer the adding of a property to a bean definition until later. This is * for a case where you assign a property to a list that may not contain bean references at that * point of assignment, but may later; hence, it would need to be managed. */ private static class DeferredProperty { private final GroovyBeanDefinitionWrapper beanDefinition; private final String name; public Object value; public DeferredProperty(GroovyBeanDefinitionWrapper beanDefinition, String name, Object value) { this.beanDefinition = beanDefinition; this.name = name; this.value = value; } public void apply() { this.beanDefinition.addProperty(this.name, this.value); } } /** A RuntimeBeanReference that takes care of adding new properties to runtime references. */ private class GroovyRuntimeBeanReference extends RuntimeBeanReference implements GroovyObject { private final GroovyBeanDefinitionWrapper beanDefinition; private MetaClass metaClass; public GroovyRuntimeBeanReference( String beanName, GroovyBeanDefinitionWrapper beanDefinition, boolean toParent) { super(beanName, toParent); this.beanDefinition = beanDefinition; this.metaClass = InvokerHelper.getMetaClass(this); } public MetaClass getMetaClass() { return this.metaClass; } public Object getProperty(String property) { if (property.equals("beanName")) { return getBeanName(); } else if (property.equals("source")) { return getSource(); } else if (this.beanDefinition != null) { return new GroovyPropertyValue( property, this.beanDefinition.getBeanDefinition().getPropertyValues().get(property)); } else { return this.metaClass.getProperty(this, property); } } public Object invokeMethod(String name, Object args) { return this.metaClass.invokeMethod(this, name, args); } public void setMetaClass(MetaClass metaClass) { this.metaClass = metaClass; } public void setProperty(String property, Object newValue) { if (!addDeferredProperty(property, newValue)) { this.beanDefinition.getBeanDefinition().getPropertyValues().add(property, newValue); } } /** * Wraps a bean definition property an ensures that any RuntimeBeanReference additions to it are * deferred for resolution later. */ private class GroovyPropertyValue extends GroovyObjectSupport { private final String propertyName; private final Object propertyValue; public GroovyPropertyValue(String propertyName, Object propertyValue) { this.propertyName = propertyName; this.propertyValue = propertyValue; } public void leftShift(Object value) { InvokerHelper.invokeMethod(this.propertyValue, "leftShift", value); updateDeferredProperties(value); } public boolean add(Object value) { boolean retVal = (Boolean) InvokerHelper.invokeMethod(this.propertyValue, "add", value); updateDeferredProperties(value); return retVal; } public boolean addAll(Collection values) { boolean retVal = (Boolean) InvokerHelper.invokeMethod(this.propertyValue, "addAll", values); for (Object value : values) { updateDeferredProperties(value); } return retVal; } public Object invokeMethod(String name, Object args) { return InvokerHelper.invokeMethod(this.propertyValue, name, args); } public Object getProperty(String name) { return InvokerHelper.getProperty(this.propertyValue, name); } public void setProperty(String name, Object value) { InvokerHelper.setProperty(this.propertyValue, name, value); } private void updateDeferredProperties(Object value) { if (value instanceof RuntimeBeanReference) { deferredProperties.put( beanDefinition.getBeanName(), new DeferredProperty(beanDefinition, this.propertyName, this.propertyValue)); } } } } }
private void initializeQuery() { query = session.createQuery(targetClass); queryMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(query.getClass()); }
public static void cleanAndRemove(MetaClassRegistryCleaner cleaner) { cleaner.clean(); GroovySystem.getMetaClassRegistry().removeMetaClassRegistryChangeEventListener(cleaner); }
public <T> Class<? extends T> generate(Class<T> type) { Map<Class, Class> cache = GENERATED_CLASSES.get(getClass()); if (cache == null) { cache = new HashMap<Class, Class>(); GENERATED_CLASSES.put(getClass(), cache); } Class generatedClass = cache.get(type); if (generatedClass != null) { return generatedClass; } if (Modifier.isPrivate(type.getModifiers())) { throw new GradleException( String.format( "Cannot create a proxy class for private class '%s'.", type.getSimpleName())); } if (Modifier.isAbstract(type.getModifiers())) { throw new GradleException( String.format( "Cannot create a proxy class for abstract class '%s'.", type.getSimpleName())); } Class<? extends T> subclass; try { ClassBuilder<T> builder = start(type); boolean isConventionAware = type.getAnnotation(NoConventionMapping.class) == null; boolean isDynamicAware = type.getAnnotation(NoDynamicObject.class) == null; builder.startClass(isConventionAware, isDynamicAware); if (isDynamicAware && !DynamicObjectAware.class.isAssignableFrom(type)) { builder.mixInDynamicAware(); } if (isDynamicAware && !GroovyObject.class.isAssignableFrom(type)) { builder.mixInGroovyObject(); } if (isDynamicAware) { builder.addDynamicMethods(); } if (isConventionAware && !IConventionAware.class.isAssignableFrom(type)) { builder.mixInConventionAware(); } Class noMappingClass = Object.class; for (Class<?> c = type; c != null && noMappingClass == Object.class; c = c.getSuperclass()) { if (c.getAnnotation(NoConventionMapping.class) != null) { noMappingClass = c; } } Collection<String> skipProperties = Arrays.asList("metaClass", "conventionMapping", "convention", "asDynamicObject"); MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(type); for (MetaProperty property : metaClass.getProperties()) { if (skipProperties.contains(property.getName())) { continue; } if (property instanceof MetaBeanProperty) { MetaBeanProperty metaBeanProperty = (MetaBeanProperty) property; MetaMethod getter = metaBeanProperty.getGetter(); if (getter == null) { continue; } if (Modifier.isFinal(getter.getModifiers()) || Modifier.isPrivate(getter.getModifiers())) { continue; } if (getter.getReturnType().isPrimitive()) { continue; } Class declaringClass = getter.getDeclaringClass().getTheClass(); if (declaringClass.isAssignableFrom(noMappingClass)) { continue; } builder.addGetter(metaBeanProperty); MetaMethod setter = metaBeanProperty.getSetter(); if (setter == null) { continue; } if (Modifier.isFinal(setter.getModifiers()) || Modifier.isPrivate(setter.getModifiers())) { continue; } builder.addSetter(metaBeanProperty); } } for (Constructor<?> constructor : type.getConstructors()) { if (Modifier.isPublic(constructor.getModifiers())) { builder.addConstructor(constructor); } } subclass = builder.generate(); } catch (Throwable e) { throw new GradleException( String.format("Could not generate a proxy class for class %s.", type.getName()), e); } cache.put(type, subclass); return subclass; }
static { setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(DomNode.class), DomNode.class); }
public static void displayVersion() { String version = GroovySystem.getVersion(); System.err.println("Groovy compiler version " + version); System.err.println("Copyright 2003-2013 The Codehaus. http://groovy.codehaus.org/"); System.err.println(""); }