You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by dr...@apache.org on 2015/09/10 14:26:54 UTC

svn commit: r1702233 - /river/jtsk/skunk/qa-refactor-namespace/trunk/src/net/jini/config/GroovyConfig.groovy

Author: dreedy
Date: Thu Sep 10 12:26:54 2015
New Revision: 1702233

URL: http://svn.apache.org/r1702233
Log:
Mods to DroovyConfig

Modified:
    river/jtsk/skunk/qa-refactor-namespace/trunk/src/net/jini/config/GroovyConfig.groovy

Modified: river/jtsk/skunk/qa-refactor-namespace/trunk/src/net/jini/config/GroovyConfig.groovy
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/net/jini/config/GroovyConfig.groovy?rev=1702233&r1=1702232&r2=1702233&view=diff
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/net/jini/config/GroovyConfig.groovy (original)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/net/jini/config/GroovyConfig.groovy Thu Sep 10 12:26:54 2015
@@ -13,32 +13,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.jini.config;
+package net.jini.config
 
-import net.jini.config.Configuration
-import net.jini.config.ConfigurationException
-import net.jini.config.NoSuchEntryException
-import net.jini.config.ConfigurationNotFoundException
-import net.jini.config.ConfigurationFile
-import java.util.logging.Logger
-import java.util.logging.Level
-import java.lang.reflect.Constructor
+import net.jini.config.*
+import org.codehaus.groovy.control.CompilerConfiguration
 
+import java.lang.reflect.Constructor
+import java.util.logging.Level
+import java.util.logging.Logger
 /**
  * Provides support for Groovy based configuration.
  *
  * @author Dennis Reedy
  */
-class GroovyConfig implements Configuration {
-    Map<String, GroovyObject> groovyConfigs = new HashMap<String, GroovyObject>()
-    ConfigurationFile configFile
-    List <String> visited = new ArrayList<String>()
-    static Logger logger = Logger.getLogger(GroovyConfig.class.getPackage().name)
+class GroovyConfig implements net.jini.config.Configuration {
+    private Map<String, GroovyObject> groovyConfigs = new HashMap<String, GroovyObject>()
+    private ConfigurationFile configFile
+    private List <String> visited = new ArrayList<String>()
+	private static Logger log = Logger.getLogger(GroovyConfig.class.getName())	
 
+    @SuppressWarnings("unused")
     GroovyConfig(String gFile) {
         File f = new File(gFile)
         GroovyClassLoader gcl = new GroovyClassLoader(getClass().getClassLoader())
-        parseAndLoad(f.newInputStream(), gcl)
+        parseAndLoad(new GroovyCodeSource(f), gcl)
     }
 
     /**
@@ -48,7 +46,7 @@ class GroovyConfig implements Configurat
         if(args==null || args.length==0) {
             configFile = new ConfigurationFile(args, loader)
         } else {
-            if(!args[0].endsWith(".groovy")) {
+            if(args[0].endsWith(".config") || args[0].equals("-")) {
                 configFile = new ConfigurationFile(args, loader)
             } else {
                 /* Make sure we have all groovy files */
@@ -59,83 +57,126 @@ class GroovyConfig implements Configurat
     }
 
     def checkInputs(String[] args) {
-        args.each { arg ->
+        for(String arg : args) {
             if(arg.endsWith(".groovy")) {
-                if(logger.isLoggable(Level.FINE))
-                logger.fine(arg)
-            } else {
+				if(log.isLoggable(Level.FINE))
+                    log.fine(arg)
+            } else if(arg.endsWith(".config")){
                 StringBuffer buffer = new StringBuffer()
                 args.each { a ->
                     buffer.append(a).append(' ')
                 }
-                throw new ConfigurationException(
-                    'When providing multiple configuration files, '+
-                    'they must all be Groovy configurations '+
-                    '['+buffer.toString()+']');
+                throw new ConfigurationException('When providing multiple configuration files, '+
+                                                 'they must all be Groovy configurations ['+buffer.toString()+']');
             }
         }
     }
 
     def traverseInputs(String[] args, ClassLoader loader) {
+        ClassLoader cCL = Thread.currentThread().getContextClassLoader()
         if(loader==null)
-            loader = Thread.currentThread().getContextClassLoader()
+            loader = cCL
         GroovyClassLoader gcl = new GroovyClassLoader(loader)
-        args.each { arg ->
-            String groovyFile = arg
-            InputStream is = null
-            long t0 = System.currentTimeMillis()
-            try {
+        Thread.currentThread().setContextClassLoader(gcl)
+        try {
+            for(String arg : args) {
+                String groovySource = arg
+                long t0 = System.currentTimeMillis()
                 try {
-                    URL url = new URL(groovyFile)
-                    is = url.openStream()
-                } catch (MalformedURLException e) {
-                    is = new FileInputStream(groovyFile);
-                }
-                parseAndLoad(is, gcl)
-            } catch (FileNotFoundException e) {
-                throw new ConfigurationNotFoundException("The configuration file "+
-                                                         +"["+groovyFile+"] "+
-                                                         +"does not exist")
-            } finally {
-                if (is != null) {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
+                    GroovyCodeSource groovyCodeSource
+                    if(groovySource.startsWith("jar:")) {
+                        String resource = groovySource
+                        int ndx = groovySource.indexOf("!")
+                        if(ndx!=-1)
+                            resource = groovySource.substring(ndx+2)
+                        groovyCodeSource = new GroovyCodeSource(loader.getResource(resource))
+                    } else {
+                        if(groovySource.startsWith("file:") || groovySource.startsWith("http:") || groovySource.startsWith("https:")) {
+                            groovyCodeSource = new GroovyCodeSource(new URL(groovySource))
+                        } else {
+                            File groovyFile = new File(groovySource)
+                            if (groovyFile.exists()) {
+                                groovyCodeSource = new GroovyCodeSource(groovyFile)
+                            } else {
+                                groovyCodeSource = new GroovyCodeSource((String)groovySource, "DynamicGroovyConfig", "groovy/script")
+                            }
+                        }
                     }
+                    parseAndLoad(groovyCodeSource, gcl)
+                } catch (FileNotFoundException e) {
+                    throw new ConfigurationNotFoundException("The configuration file [${groovySource}] does not exist", e)
+                } catch(Throwable t) {
+                    throw new ConfigurationException("The configuration file [${groovySource}] could not be parsed", t)
+                } finally {
+					if(log.isLoggable(Level.FINE))
+                        log.fine "Time to parse ${groovySource} : ${(System.currentTimeMillis()-t0)} milliseconds"
                 }
-                if(logger.isLoggable(Level.FINE))
-                    logger.fine 'Time to parse '+groovyFile+' : '+
-                                (System.currentTimeMillis()-t0)+' '+
-                                'milliseconds'
             }
+        } finally {
+            Thread.currentThread().setContextClassLoader(cCL)
+            gcl = null
         }
+    }
 
+    def clear() {
+        visited.clear()
+        if(groovyConfigs!=null) {
+            /*for(Map.Entry<String, GroovyObject> entry : groovyConfigs)  {
+                InvokerHelper.removeClass(entry.value.class)
+            }*/
+            groovyConfigs.clear()
+            groovyConfigs = null
+        }
     }
 
-    def parseAndLoad(InputStream is, GroovyClassLoader gcl) {
-        gcl.parseClass(is)
-        for(Class groovyClass : gcl.loadedClasses) {
-            if(visited.contains(groovyClass.name))
-                continue
-            visited.add(groovyClass.name)
-            for(Constructor c : groovyClass.getConstructors())  {
-                if(c.parameterTypes.length==0) {
-                    c.setAccessible(true)
-                    GroovyObject gO = (GroovyObject)c.newInstance()
-                    String component
-                    if(groovyClass.isAnnotationPresent(Component.class)) {
-                        Component comp = groovyClass.getAnnotation(Component.class)
-                        component = comp.value()
-                    } else {
-                        component = getComponentName(gO.getMetaClass())
-                    }
-                    if (!validQualifiedIdentifier(component)) {
-                        throw new IllegalArgumentException(
-                            "component must be a valid qualified identifier");
-                    }
-                    groovyConfigs.put(component, gO)
+    def parseAndLoad(GroovyCodeSource groovyCodeSource, GroovyClassLoader gcl) {
+        if(groovyCodeSource.getName().endsWith(".class")) {
+            GroovyClassLoader newCl
+            try {
+                CompilerConfiguration config = new CompilerConfiguration()
+                config.classpath = groovyCodeSource.file.parentFile.path
+                newCl = new GroovyClassLoader(gcl, config, true)
+                String name = groovyCodeSource.file.name.substring(0, groovyCodeSource.file.name.indexOf("."))
+                load(newCl.loadClass(name))
+            } catch(Throwable t) {
+                throw t
+            } finally {
+                newCl = null
+            }
+        } else {
+            gcl.parseClass(groovyCodeSource)
+            for(Class groovyClass : gcl.loadedClasses) {
+                load(groovyClass)
+            }
+        }
+    }
+
+    def load(Class groovyClass)  {
+		if(log.isLoggable(Level.FINE))
+            log.fine("Loading "+ groovyClass.name)
+        if(visited.contains(groovyClass.name))
+            return
+        visited.add(groovyClass.name)
+        for(Constructor c : groovyClass.getConstructors())  {
+            if(c.parameterTypes.length==0) {
+                c.setAccessible(true)
+                GroovyObject gO = (GroovyObject)c.newInstance()
+                String component
+                if(groovyClass.isAnnotationPresent(Component.class)) {
+                    Component comp = groovyClass.getAnnotation(Component.class)
+                    component = comp.value()
+					if(log.isLoggable(Level.FINE))	
+                        log.fine("Found component: ${component} from annotation")
+                } else {
+                    component = getComponentName(gO.getMetaClass())
+					if(log.isLoggable(Level.FINE))	
+                        log.fine("Derived component: ${component} from metaclass")
+                }
+                if (!validQualifiedIdentifier(component)) {
+                    throw new IllegalArgumentException("component must be a valid qualified identifier");
                 }
-            }            
+                groovyConfigs.put(component, gO)
+            }
         }
     }
 
@@ -144,7 +185,7 @@ class GroovyConfig implements Configurat
         component = component.replace("_", ".")
         return component
     }
-    
+
     def Object getEntry(String component, String name, Class type) {
         return getEntry(component, name, type, NO_DEFAULT);
     }
@@ -156,7 +197,8 @@ class GroovyConfig implements Configurat
     def Object getEntry(String component, String name, Class type, Object defaultValue, Object data) {
         if(configFile!=null)
             return configFile.getEntry(component, name, type, defaultValue, data)
-
+		if(log.isLoggable(Level.FINE))		
+            log.fine("component=${component}, name=${name}, type=${type.getName()}, defautValue=${defaultValue}, data=${data}")
         if (component == null) {
             throw new NullPointerException("component cannot be null");
         } else if (name == null) {
@@ -174,6 +216,8 @@ class GroovyConfig implements Configurat
 
         GroovyObject groovyConfig = null;
         for(Map.Entry<String, GroovyObject> entry : groovyConfigs)  {
+			if(log.isLoggable(Level.FINE))	
+                log.fine("component: ${component}, found: ${entry.key}")
             if(entry.key.equals(component)) {
                 groovyConfig = entry.value;
                 break;
@@ -181,9 +225,8 @@ class GroovyConfig implements Configurat
         }
         if(groovyConfig==null) {
             if(defaultValue==NO_DEFAULT)
-                throw new NoSuchEntryException('component name ['+component+'] '+
-                                               'not found in Groovy files, '+
-                                               'and no default value was given.')
+                throw new NoSuchEntryException("component name [${component}] not found in Groovy files, "+
+                                               "and no default value was given.")
             else
                 return defaultValue;
         }
@@ -192,28 +235,22 @@ class GroovyConfig implements Configurat
         if(data==NO_DATA) {
             try {
                 value = groovyConfig.getProperty(name)
-                if(logger.isLoggable(Level.FINER))
-                    logger.finer 'Configuration entry '+
-                                 '['+component+'.'+name+'] found in '+
-                                 'GroovyObject '+groovyConfig+', '+
-                                 'asssign returned value: '+value
+				if(log.isLoggable(Level.FINE))	
+                    log.fine "Configuration entry [${component}.${name}] found in "+
+                              "GroovyObject ${groovyConfig}, assign returned value: ${value}"
             } catch(MissingPropertyException e) {
-                if(logger.isLoggable(Level.FINEST))
-                    logger.log(Level.FINEST,
-                               'Looking for configuration entry '+
-                               '['+component+'.'+name+'] in GroovyObject '+
-                               groovyConfig,
-                               e)
+                if(!e.getProperty().equals(name))
+                    throw new ConfigurationException(e.getMessage(), e)
+				if(log.isLoggable(Level.FINE))	
+                    log.fine("${e.getClass().getName()}: looking for configuration entry "+
+                             "[${component}.${name}] in GroovyObject "+
+                             groovyConfig)
                 if(defaultValue==NO_DEFAULT) {
-                    throw new NoSuchEntryException("entry not found for "+
-                                                   "component: "+component +", "+
-                                                   "name: " + name, e);
+                    throw new NoSuchEntryException("entry not found for component: $component, name: $name", e);
                 } else {
-                    if(logger.isLoggable(Level.FINER))
-                        logger.finer 'Configuration entry '+
-                                     '['+component+'.'+name+'] not found in '+
-                                     'GroovyObject '+groovyConfig+', '+
-                                     'asssign provided default: '+defaultValue
+					if(log.isLoggable(Level.FINE))	
+                        log.fine "Configuration entry [${component}.${name}] not found in "+
+                                  "GroovyObject ${groovyConfig}, assign provided default: ${defaultValue}"
                     value = defaultValue;
                 }
             }
@@ -224,9 +261,7 @@ class GroovyConfig implements Configurat
                 List<MetaMethod> methods = groovyConfig.metaClass.methods
                 for(MetaMethod m : methods) {
                     if(m.name==methodName) {
-                        if(logger.isLoggable(Level.FINEST))
-                            logger.finest "Found matching method name [${methodName}], "+
-                                          "check for type match"
+                        log.trace "Found matching method name [${methodName}], check for type match"
                         Class[] paramTypes = m.nativeParameterTypes
                         if(paramTypes.length==1 && paramTypes[0].isAssignableFrom(data.class)) {
                             mm = m;
@@ -236,19 +271,16 @@ class GroovyConfig implements Configurat
                 }
                 if(mm==null) {
                     if(defaultValue==NO_DEFAULT)
-                        throw new NoSuchEntryException("entry not found for "+
-                                                       "component: "+component+", "+
-                                                       "name: " + name+", "+
-                                                       "data argument: "+data);
+                        throw new NoSuchEntryException("entry not found for component: $component, "+
+                                                       "name: $name, data argument: $data");
 
                     value = defaultValue;
                 } else {
                     value = mm.invoke(groovyConfig, data)
                 }
             } catch(MissingPropertyException e) {
-                throw new NoSuchEntryException("entry not found for component: " +
-                                               component +", name: " + name+", "+
-                                                   "data argument: "+data, e);
+                throw new NoSuchEntryException("entry not found for component: $component, name: $name, "+
+                                               "data argument: $data", e);
             }
         }
 
@@ -262,10 +294,9 @@ class GroovyConfig implements Configurat
                 mismatch = true
             }
             if(mismatch) {
-                throw new ConfigurationException(
-                    "entry for component " + component + ", name " + name +" "+
-                    "is of wrong type: " +value.getClass().name+", "+
-                    "expected: "+type.name);
+                throw new ConfigurationException("entry for component $component, name $name "+
+                                                 "is of wrong type: ${value.getClass().name}, "+
+                                                 "expected: ${type.name}");
             }
         }
         return value