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

org.codehaus.groovy.runtime.m12n.SimpleExtensionModule Maven / Gradle / Ivy

The 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 org.codehaus.groovy.runtime.m12n;

import groovy.lang.MetaMethod;
import org.codehaus.groovy.reflection.CachedClass;
import org.codehaus.groovy.reflection.CachedMethod;
import org.codehaus.groovy.reflection.ReflectionCache;
import org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod;
import org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod;

import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

/**
 * An extension module which provides extension methods using a {@link org.codehaus.groovy.runtime.DefaultGroovyMethods}-like implementation, that
 * is to say using static methods defined in an "extension class".
 * 

* For commodity, multiple extension classes may be defined in a single module, including classes used to define new * static methods. *

* Modules are required to implement the {@link #getInstanceMethodsExtensionClasses} for classes defining new instance * methods, and {@link #getStaticMethodsExtensionClasses()} for classes defining static methods. *

* For example, to define a module adding methods to the {@link String} class, you can write a helper class: *

 * class StringExtension {
 *     public static int count(String self, char c) {
 *         int result = 0;
 *         for (int i=0;i<self.length(); i++) {
 *             if (self.charAt(i)==c) result++;
 *         }
 *         return result;
 *     }
 * }
 * 
*

* This class defines a single static method taking the string instance as first argument, allowing to define * a new instance method on the String class:

String#count(char c)
. *

* To define a new static method on a class, as the static modifier is already used for instance methods, you must use * another helper class, for example: *

*

 * class StaticStringExtension {
 *     public static void foo(String self) { System.out.println("foo"); }
 * }
 * 
*

* The first argument of the method is only used to tell the class for which we add a static method. You can now define * an extension module: *

*

 * class MyStringModule extends SimpleExtensionModule {
 *     // ...
 *
 *     public List<Class> getInstanceMethodsExtensionClasses() {
 *         return Collections.singletonList(StringExtension.class);
 *     }
 *
 *     public List<Class> getStaticMethodsExtensionClasses() {
 *         return Collections.singletonList(StaticStringExtension.class);
 *     }
 * }
 * 
* * @author Cedric Champeau * @since 2.0.0 */ public abstract class SimpleExtensionModule extends ExtensionModule { private static final Logger LOG = Logger.getLogger(SimpleExtensionModule.class.getName()); public SimpleExtensionModule(final String moduleName, final String moduleVersion) { super(moduleName, moduleVersion); } @Override public List getMetaMethods() { List metaMethods = new LinkedList(); List extensionClasses = getInstanceMethodsExtensionClasses(); for (Class extensionClass : extensionClasses) { try { createMetaMethods(extensionClass, metaMethods, false); } catch (LinkageError e) { LOG.warning("Module ["+getName()+"] - Unable to load extension class ["+extensionClass+"] due to ["+e.getMessage()+"]. Maybe this module is not supported by your JVM version."); } } extensionClasses = getStaticMethodsExtensionClasses(); for (Class extensionClass : extensionClasses) { try { createMetaMethods(extensionClass, metaMethods, true); } catch (LinkageError e) { LOG.warning("Module ["+getName()+"] - Unable to load extension class ["+extensionClass+"] due to ["+e.getMessage()+"]. Maybe this module is not supported by your JVM version."); } } return metaMethods; } private static void createMetaMethods(final Class extensionClass, final List metaMethods, final boolean isStatic) { CachedClass cachedClass = ReflectionCache.getCachedClass(extensionClass); CachedMethod[] methods = cachedClass.getMethods(); for (CachedMethod method : methods) { if (method.isStatic() && method.isPublic() && method.getParamsCount() > 0) { // an extension method is found metaMethods.add(isStatic?new NewStaticMetaMethod(method) : new NewInstanceMetaMethod(method)); } } } /** * @return the list of classes defining new instance methods. */ public abstract List getInstanceMethodsExtensionClasses(); /** * @return the list of classes defining new static methods. */ public abstract List getStaticMethodsExtensionClasses(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy