You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 04:29:30 UTC
[22/47] groovy git commit: Move source files to proper packages
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/PermutationGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/PermutationGenerator.java b/src/main/groovy/groovy/util/PermutationGenerator.java
new file mode 100644
index 0000000..a9b68e2
--- /dev/null
+++ b/src/main/groovy/groovy/util/PermutationGenerator.java
@@ -0,0 +1,149 @@
+/*
+ * 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 org.codehaus.groovy.runtime.DefaultGroovyMethods;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Systematically generate permutations.
+ *
+ * Adapted from Java Code by Michael Gilleland (released with no restrictions) using an algorithm described here:
+ * Kenneth H. Rosen, Discrete Mathematics and Its Applications, 2nd edition (NY: McGraw-Hill, 1991), pp. 282-284
+ */
+public class PermutationGenerator<E> implements Iterator<List<E>> {
+ private final int[] a;
+ private BigInteger numLeft;
+ private final BigInteger total;
+ private final List<E> items;
+
+ /**
+ * WARNING: Don't make n too large.
+ * Recall that the number of permutations is n!
+ * which can be very large, even when n is as small as 20 --
+ * 20! = 2,432,902,008,176,640,000 and
+ * 21! is too big to fit into a Java long, which is
+ * why we use BigInteger instead.
+ *
+ * @param items the items to permute
+ */
+ public PermutationGenerator(Collection<E> items) {
+ this.items = new ArrayList<E>(items);
+ int n = items.size();
+ if (n < 1) {
+ throw new IllegalArgumentException("At least one item required");
+ }
+ a = new int[n];
+ total = getFactorial(n);
+ reset();
+ }
+
+ public PermutationGenerator(Iterable<E> items) {
+ this(DefaultGroovyMethods.asCollection(items));
+ }
+
+ public void reset() {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ numLeft = new BigInteger(total.toString());
+ }
+
+ public BigInteger getTotal() {
+ return total;
+ }
+
+ public boolean hasNext() {
+ return numLeft.compareTo(BigInteger.ZERO) == 1;
+ }
+
+ /**
+ * Compute factorial (TODO: expose this)
+ *
+ * @param n the input integer
+ * @return the factorial for n
+ */
+ private static BigInteger getFactorial(int n) {
+ BigInteger fact = BigInteger.ONE;
+ for (int i = n; i > 1; i--) {
+ fact = fact.multiply(new BigInteger(Integer.toString(i)));
+ }
+ return fact;
+ }
+
+ /**
+ * Generate next permutation (algorithm from Rosen p. 284)
+ *
+ * @return the items permuted
+ */
+ public List<E> next() {
+ if (numLeft.equals(total)) {
+ numLeft = numLeft.subtract(BigInteger.ONE);
+ return items;
+ }
+
+ int temp;
+
+ // Find largest index j with a[j] < a[j+1]
+ int j = a.length - 2;
+ while (a[j] > a[j + 1]) {
+ j--;
+ }
+
+ // Find index k such that a[k] is smallest integer
+ // greater than a[j] to the right of a[j]
+ int k = a.length - 1;
+ while (a[j] > a[k]) {
+ k--;
+ }
+
+ // Interchange a[j] and a[k]
+ temp = a[k];
+ a[k] = a[j];
+ a[j] = temp;
+
+ // Put tail end of permutation after jth position in increasing order
+ int r = a.length - 1;
+ int s = j + 1;
+
+ while (r > s) {
+ temp = a[s];
+ a[s] = a[r];
+ a[r] = temp;
+ r--;
+ s++;
+ }
+
+ numLeft = numLeft.subtract(BigInteger.ONE);
+ List<E> ans = new ArrayList<E>(a.length);
+ for (int index : a) {
+ ans.add(items.get(index));
+ }
+ return ans;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("remove() not allowed for PermutationGenerator");
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/Proxy.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/Proxy.java b/src/main/groovy/groovy/util/Proxy.java
new file mode 100644
index 0000000..ac080b3
--- /dev/null
+++ b/src/main/groovy/groovy/util/Proxy.java
@@ -0,0 +1,70 @@
+/*
+ * 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.GroovyObjectSupport;
+import groovy.lang.MissingMethodException;
+import org.codehaus.groovy.runtime.InvokerHelper;
+
+import java.util.Iterator;
+
+/**
+ * Dynamic groovy proxy for another object. All method
+ * invocations get forwarded to actual object, unless the proxy overrides it.
+ * See groovy/util/ProxyTest.groovy for usage details.
+ *
+ * @author Troy Heninger
+ * @author Dierk Koenig
+ */
+public class Proxy extends GroovyObjectSupport {
+
+ private Object adaptee = null;
+
+ /**
+ * This method is for convenience.
+ * It allows to get around the need for defining dump ctors in subclasses.
+ * See unit tests for details.
+ */
+ public Proxy wrap(Object adaptee){
+ setAdaptee(adaptee);
+ return this;
+ }
+
+ public Object getAdaptee() {
+ return adaptee;
+ }
+
+ public void setAdaptee(Object adaptee) {
+ this.adaptee = adaptee;
+ }
+
+ public Object invokeMethod(String name, Object args) {
+ try {
+ return super.invokeMethod(name, args);
+ }
+ catch (MissingMethodException e) {
+ return InvokerHelper.invokeMethod(adaptee, name, args);
+ }
+ }
+
+ public Iterator iterator() {
+ return InvokerHelper.asIterator(adaptee);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ProxyGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ProxyGenerator.java b/src/main/groovy/groovy/util/ProxyGenerator.java
new file mode 100644
index 0000000..da12b97
--- /dev/null
+++ b/src/main/groovy/groovy/util/ProxyGenerator.java
@@ -0,0 +1,339 @@
+/*
+ * 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.Closure;
+import groovy.lang.DelegatingMetaClass;
+import groovy.lang.GroovyObject;
+import groovy.lang.GroovySystem;
+import groovy.lang.MetaClass;
+import org.codehaus.groovy.runtime.InvokerHelper;
+import org.codehaus.groovy.runtime.ProxyGeneratorAdapter;
+import org.codehaus.groovy.runtime.memoize.LRUCache;
+import org.codehaus.groovy.runtime.typehandling.GroovyCastException;
+import org.codehaus.groovy.transform.trait.Traits;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Classes to generate 'Proxy' objects which implement interfaces,
+ * maps of closures and/or extend classes/delegates.
+ *
+ * @author Paul King
+ * @author Guillaume Laforge
+ * @author Cedric Champeau
+ */
+public class ProxyGenerator {
+ private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+ private static final Class[] EMPTY_INTERFACE_ARRAY = EMPTY_CLASS_ARRAY;
+ private static final Map<Object,Object> EMPTY_CLOSURE_MAP = Collections.emptyMap();
+ private static final Set<String> EMPTY_KEYSET = Collections.emptySet();
+
+ public static final ProxyGenerator INSTANCE = new ProxyGenerator();
+
+ static {
+ // wrap the standard MetaClass with the delegate
+ setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(ProxyGenerator.class));
+ }
+
+ private ClassLoader override = null;
+ private boolean debug = false;
+ private boolean emptyMethods = false;
+
+ /**
+ * The adapter cache is used to cache proxy classes. When, for example, a call like:
+ * map as MyClass is found, then a lookup is made into the cache to find if a suitable
+ * adapter already exists. If so, then the class is reused, instead of generating a
+ * new class.
+ */
+ private final LRUCache adapterCache = new LRUCache(16);
+
+ public boolean getDebug() {
+ return debug;
+ }
+
+ /**
+ * Instructs <code>ProxyGenerator</code> to dump generated Groovy
+ * source code to standard output during construction. This is useful
+ * for debugging purposes but should be turned off in production.
+ *
+ * @param debug true if you want generated source to be printed
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ public boolean getEmptyMethods() {
+ return emptyMethods;
+ }
+
+ /**
+ * Changes generated methods to have empty implementations.
+ * <p>
+ * Methods in generated aggregates not supplied in a closures map or
+ * base class are given 'default' implementations. The implementation
+ * will normally throw an <code>UnsupportedOperationException</code>
+ * but setting this boolean will leave it empty.
+ *
+ * @param emptyMethods true if you want generated methods to be empty
+ */
+ public void setEmptyMethods(boolean emptyMethods) {
+ this.emptyMethods = emptyMethods;
+ }
+
+ public ClassLoader getOverride() {
+ return override;
+ }
+
+ public void setOverride(ClassLoader override) {
+ this.override = override;
+ }
+
+ public GroovyObject instantiateAggregateFromBaseClass(Class clazz) {
+ return instantiateAggregateFromBaseClass((Map) null, clazz);
+ }
+
+ public GroovyObject instantiateAggregateFromBaseClass(Map map, Class clazz) {
+ return instantiateAggregateFromBaseClass(map, clazz, null);
+ }
+
+ public GroovyObject instantiateAggregateFromBaseClass(Closure cl, Class clazz) {
+ Map<String, Closure> m = new HashMap<String, Closure>();
+ m.put("*", cl);
+ return instantiateAggregateFromBaseClass(m, clazz, null);
+ }
+
+ public GroovyObject instantiateAggregateFromBaseClass(Class clazz, Object[] constructorArgs) {
+ return instantiateAggregate(null, null, clazz, constructorArgs);
+ }
+
+ public GroovyObject instantiateAggregateFromBaseClass(Map map, Class clazz, Object[] constructorArgs) {
+ return instantiateAggregate(map, null, clazz, constructorArgs);
+ }
+
+ public GroovyObject instantiateAggregateFromInterface(Class clazz) {
+ return instantiateAggregateFromInterface(null, clazz);
+ }
+
+ public GroovyObject instantiateAggregateFromInterface(Map map, Class clazz) {
+ List<Class> interfaces = new ArrayList<Class>();
+ interfaces.add(clazz);
+ return instantiateAggregate(map, interfaces);
+ }
+
+ public GroovyObject instantiateAggregate(List<Class> interfaces) {
+ return instantiateAggregate(null, interfaces);
+ }
+
+ public GroovyObject instantiateAggregate(Map closureMap, List<Class> interfaces) {
+ return instantiateAggregate(closureMap, interfaces, null);
+ }
+
+ public GroovyObject instantiateAggregate(Map closureMap, List<Class> interfaces, Class clazz) {
+ return instantiateAggregate(closureMap, interfaces, clazz, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public GroovyObject instantiateAggregate(Map closureMap, List<Class> interfaces, Class clazz, Object[] constructorArgs) {
+ if (clazz != null && Modifier.isFinal(clazz.getModifiers())) {
+ throw new GroovyCastException("Cannot coerce a map to class " + clazz.getName() + " because it is a final class");
+ }
+ Map<Object,Object> map = closureMap != null ? closureMap : EMPTY_CLOSURE_MAP;
+ ProxyGeneratorAdapter adapter = createAdapter(map, interfaces, null, clazz);
+
+ return adapter.proxy(map, constructorArgs);
+ }
+
+ public GroovyObject instantiateDelegate(Object delegate) {
+ return instantiateDelegate(null, delegate);
+ }
+
+ public GroovyObject instantiateDelegate(List<Class> interfaces, Object delegate) {
+ return instantiateDelegate(null, interfaces, delegate);
+ }
+
+ public GroovyObject instantiateDelegate(Map closureMap, List<Class> interfaces, Object delegate) {
+ return instantiateDelegateWithBaseClass(closureMap, interfaces, delegate, null);
+ }
+
+ public GroovyObject instantiateDelegateWithBaseClass(Map closureMap, List<Class> interfaces, Object delegate) {
+ return instantiateDelegateWithBaseClass(closureMap, interfaces, delegate, delegate.getClass());
+ }
+
+ public GroovyObject instantiateDelegateWithBaseClass(Map closureMap, List<Class> interfaces, Object delegate, Class baseClass) {
+ return instantiateDelegateWithBaseClass(closureMap, interfaces, delegate, baseClass, null);
+ }
+
+ /**
+ * Creates a proxy with a delegate object.
+ *
+ * @param closureMap the closure for methods not handled by the delegate
+ * @param interfaces interfaces to be implemented
+ * @param delegate the delegate object
+ * @param baseClass the base class
+ * @param name the name of the proxy, unused, but kept for compatibility with previous versions of Groovy.
+ * @return a proxy object implementing the specified interfaces, and delegating to the provided object
+ */
+ @SuppressWarnings("unchecked")
+ public GroovyObject instantiateDelegateWithBaseClass(Map closureMap, List<Class> interfaces, Object delegate, Class baseClass, String name) {
+ Map<Object,Object> map = closureMap != null ? closureMap : EMPTY_CLOSURE_MAP;
+ ProxyGeneratorAdapter adapter = createAdapter(map, interfaces, delegate.getClass(), baseClass);
+
+ return adapter.delegatingProxy(delegate, map, (Object[])null);
+ }
+
+ private ProxyGeneratorAdapter createAdapter(Map closureMap, List<Class> interfaces, Class delegateClass, Class baseClass) {
+ // According to https://shipilev.net/blog/2016/arrays-wisdom-ancients/#_conclusion
+ // toArray(new T[0]) seems faster, safer, and contractually cleaner, and therefore should be the default choice now.
+ Class[] intfs = interfaces != null ? interfaces.toArray(EMPTY_CLASS_ARRAY) : EMPTY_INTERFACE_ARRAY;
+ Class base = baseClass;
+ if (base == null) {
+ if (intfs.length > 0) {
+ base = intfs[0];
+ } else {
+ base = Object.class;
+ }
+ }
+ Set<String> keys = closureMap == EMPTY_CLOSURE_MAP ? EMPTY_KEYSET : new HashSet<String>();
+ for (Object o : closureMap.keySet()) {
+ keys.add(o.toString());
+ }
+ boolean useDelegate = null != delegateClass;
+ CacheKey key = new CacheKey(base, useDelegate ? delegateClass : Object.class, keys, intfs, emptyMethods, useDelegate);
+ ProxyGeneratorAdapter adapter = (ProxyGeneratorAdapter) adapterCache.get(key);
+ if (adapter == null) {
+ adapter = new ProxyGeneratorAdapter(closureMap, base, intfs, useDelegate ? delegateClass.getClassLoader() : base.getClassLoader(), emptyMethods, useDelegate ? delegateClass : null);
+ adapterCache.put(key, adapter);
+ }
+
+ return adapter;
+ }
+
+ private static void setMetaClass(final MetaClass metaClass) {
+ final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
+ @Override
+ public Object invokeStaticMethod(Object object, String methodName, Object[] arguments) {
+ return InvokerHelper.invokeMethod(INSTANCE, methodName, arguments);
+ }
+ };
+ GroovySystem.getMetaClassRegistry().setMetaClass(ProxyGenerator.class, newMetaClass);
+ }
+
+ private static final class CacheKey {
+ private static final Comparator<Class> INTERFACE_COMPARATOR = new Comparator<Class>() {
+ public int compare(final Class o1, final Class o2) {
+ // Traits order *must* be preserved
+ // See GROOVY-7285
+ if (Traits.isTrait(o1)) return -1;
+ if (Traits.isTrait(o2)) return 1;
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+ private final boolean emptyMethods;
+ private final boolean useDelegate;
+ private final Set<String> methods;
+ private final ClassReference delegateClass;
+ private final ClassReference baseClass;
+ private final ClassReference[] interfaces;
+
+ private CacheKey(final Class baseClass, final Class delegateClass, final Set<String> methods, final Class[] interfaces, final boolean emptyMethods, final boolean useDelegate) {
+ this.useDelegate = useDelegate;
+ this.baseClass = new ClassReference(baseClass);
+ this.delegateClass = new ClassReference(delegateClass);
+ this.emptyMethods = emptyMethods;
+ this.interfaces = interfaces == null ? null : new ClassReference[interfaces.length];
+ if (interfaces != null) {
+ Class[] interfacesCopy = new Class[interfaces.length];
+ System.arraycopy(interfaces, 0, interfacesCopy, 0, interfaces.length);
+ Arrays.sort(interfacesCopy, INTERFACE_COMPARATOR);
+ for (int i = 0; i < interfacesCopy.length; i++) {
+ Class anInterface = interfacesCopy[i];
+ this.interfaces[i] = new ClassReference(anInterface);
+ }
+ }
+ this.methods = methods;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final CacheKey cacheKey = (CacheKey) o;
+
+ if (emptyMethods != cacheKey.emptyMethods) return false;
+ if (useDelegate != cacheKey.useDelegate) return false;
+ if (baseClass != null ? !baseClass.equals(cacheKey.baseClass) : cacheKey.baseClass != null) return false;
+ if (delegateClass != null ? !delegateClass.equals(cacheKey.delegateClass) : cacheKey.delegateClass != null) return false;
+ if (!Arrays.equals(interfaces, cacheKey.interfaces)) return false;
+ if (methods != null ? !methods.equals(cacheKey.methods) : cacheKey.methods != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (emptyMethods ? 1 : 0);
+ result = 31 * result + (useDelegate ? 1 : 0);
+ result = 31 * result + (methods != null ? methods.hashCode() : 0);
+ result = 31 * result + (baseClass != null ? baseClass.hashCode() : 0);
+ result = 31 * result + (delegateClass != null ? delegateClass.hashCode() : 0);
+ result = 31 * result + (interfaces != null ? Arrays.hashCode(interfaces) : 0);
+ return result;
+ }
+
+ /**
+ * A weak reference which delegates equals and hashcode to the referent.
+ */
+ private static class ClassReference extends WeakReference<Class> {
+
+ public ClassReference(Class referent) {
+ super(referent);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Class thisClass = this.get();
+ ClassReference that = (ClassReference) o;
+ if (thisClass == null) return false;
+ return thisClass.equals(that.get());
+ }
+
+ @Override
+ public int hashCode() {
+ Class thisClass = this.get();
+ if (thisClass == null) return 0;
+ return thisClass.hashCode();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ResourceConnector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ResourceConnector.java b/src/main/groovy/groovy/util/ResourceConnector.java
new file mode 100644
index 0000000..81e329a
--- /dev/null
+++ b/src/main/groovy/groovy/util/ResourceConnector.java
@@ -0,0 +1,37 @@
+/*
+ * 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 java.net.URLConnection;
+
+/**
+ * Base interface for customizing where resources can be found for the <code>GroovyScriptEngine</code>.
+ *
+ * @author sam
+ */
+public interface ResourceConnector {
+
+ /**
+ * Retrieve a URLConnection to a script referenced by name.
+ *
+ * @param name
+ * @throws ResourceException
+ */
+ URLConnection getResourceConnection(String name) throws ResourceException;
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ResourceException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ResourceException.java b/src/main/groovy/groovy/util/ResourceException.java
new file mode 100644
index 0000000..8b31d7e
--- /dev/null
+++ b/src/main/groovy/groovy/util/ResourceException.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+/**
+ * @author sam
+ */
+public class ResourceException extends Exception {
+
+ /**
+ *
+ */
+ public ResourceException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param message
+ */
+ public ResourceException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public ResourceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * @param cause
+ */
+ public ResourceException(Throwable cause) {
+ super(cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ScriptException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ScriptException.java b/src/main/groovy/groovy/util/ScriptException.java
new file mode 100644
index 0000000..85ce60f
--- /dev/null
+++ b/src/main/groovy/groovy/util/ScriptException.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+/**
+ * @author sam
+ */
+public class ScriptException extends Exception {
+
+ /**
+ *
+ */
+ public ScriptException() {
+ super();
+ }
+
+ /**
+ * @param message
+ */
+ public ScriptException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public ScriptException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * @param cause
+ */
+ public ScriptException(Throwable cause) {
+ super(cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Commons.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Commons.java b/src/main/groovy/groovy/util/logging/Commons.java
new file mode 100644
index 0000000..aa456d2
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Commons.java
@@ -0,0 +1,108 @@
+/*
+ * 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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * Apache Commons logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameEnabled() {
+ * log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @author Hamlet D'Arcy
+ * @author Matthias Cullmann
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Commons {
+ String value() default "log";
+ String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+ Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default CommonsLoggingStrategy.class;
+
+ public static class CommonsLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+
+ private static final String LOGGER_NAME = "org.apache.commons.logging.Log";
+ private static final String LOGGERFACTORY_NAME = "org.apache.commons.logging.LogFactory";
+
+ protected CommonsLoggingStrategy(final GroovyClassLoader loader) {
+ super(loader);
+ }
+
+ public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+ return classNode.addField(logFieldName,
+ Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+ classNode(LOGGER_NAME),
+ new MethodCallExpression(
+ new ClassExpression(classNode(LOGGERFACTORY_NAME)),
+ "getLog",
+ new ConstantExpression(getCategoryName(classNode, categoryName))));
+ }
+
+ public boolean isLoggingMethod(String methodName) {
+ return methodName.matches("fatal|error|warn|info|debug|trace");
+ }
+
+ public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+ MethodCallExpression condition = new MethodCallExpression(
+ logVariable,
+ "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+ ArgumentListExpression.EMPTY_ARGUMENTS);
+ condition.setImplicitThis(false);
+
+ return new TernaryExpression(
+ new BooleanExpression(condition),
+ originalExpression,
+ ConstantExpression.NULL);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Log.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Log.java b/src/main/groovy/groovy/util/logging/Log.java
new file mode 100644
index 0000000..e52d39b
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Log.java
@@ -0,0 +1,124 @@
+/*
+ * 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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.AttributeExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.codehaus.groovy.transform.LogASTTransformation.LoggingStrategy;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * java.util.logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isLoggable(Level.NAME) {
+ * log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, fine, finer, finest, config, warning, severe.
+ * NAME is name transformed to upper case. if anything else is used it will result in
+ * an exception at runtime. If the expression exp is a constant or only a variable access
+ * the method call will not be transformed. But this will still cause a call on the injected
+ * logger.
+ *
+ * @author Guillaume Laforge
+ * @author Jochen Theodorou
+ * @author Dinko Srkoc
+ * @author Hamlet D'Arcy
+ * @author Raffaele Cigni
+ * @author Alberto Vilches Raton
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Log {
+ String value() default "log";
+ String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+ Class<? extends LoggingStrategy> loggingStrategy() default JavaUtilLoggingStrategy.class;
+
+ /**
+ * This class contains the logic of how to weave a Java Util Logging logger into the host class.
+ */
+ public static class JavaUtilLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+
+ private static final ClassNode LOGGER_CLASSNODE = ClassHelper.make(java.util.logging.Logger.class);
+ private static final ClassNode LEVEL_CLASSNODE = ClassHelper.make(java.util.logging.Level.class);
+
+ protected JavaUtilLoggingStrategy(final GroovyClassLoader loader) {
+ super(loader);
+ }
+
+ public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+ return classNode.addField(logFieldName,
+ Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+ LOGGER_CLASSNODE,
+ new MethodCallExpression(
+ new ClassExpression(LOGGER_CLASSNODE),
+ "getLogger",
+ new ConstantExpression(getCategoryName(classNode, categoryName))));
+ }
+
+ public boolean isLoggingMethod(String methodName) {
+ return methodName.matches("severe|warning|info|fine|finer|finest");
+ }
+
+ public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+ AttributeExpression logLevelExpression = new AttributeExpression(
+ new ClassExpression(LEVEL_CLASSNODE),
+ new ConstantExpression(methodName.toUpperCase(Locale.ENGLISH)));
+
+ ArgumentListExpression args = new ArgumentListExpression();
+ args.addExpression(logLevelExpression);
+ MethodCallExpression condition = new MethodCallExpression(logVariable, "isLoggable", args);
+ condition.setImplicitThis(false);
+
+ return new TernaryExpression(
+ new BooleanExpression(condition),
+ originalExpression,
+ ConstantExpression.NULL);
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Log4j.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Log4j.java b/src/main/groovy/groovy/util/logging/Log4j.java
new file mode 100644
index 0000000..2dfdf7f
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Log4j.java
@@ -0,0 +1,119 @@
+/*
+ * 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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.AttributeExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * Log4j logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameEnabled() {
+ * log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @author Hamlet D'Arcy
+ * @author Tomek Bujok
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Log4j {
+ String value() default "log";
+ String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+ Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default Log4jLoggingStrategy.class;
+
+ public static class Log4jLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+ private static final String LOGGER_NAME = "org.apache.log4j.Logger";
+ private static final String PRIORITY_NAME = "org.apache.log4j.Priority";
+
+ protected Log4jLoggingStrategy(final GroovyClassLoader loader) {
+ super(loader);
+ }
+
+ public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+ return classNode.addField(logFieldName,
+ Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+ classNode(LOGGER_NAME),
+ new MethodCallExpression(
+ new ClassExpression(classNode(LOGGER_NAME)),
+ "getLogger",
+ new ConstantExpression(getCategoryName(classNode, categoryName))));
+ }
+
+ public boolean isLoggingMethod(String methodName) {
+ return methodName.matches("fatal|error|warn|info|debug|trace");
+ }
+
+ public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+ final MethodCallExpression condition;
+ if (!"trace".equals(methodName)) {
+ AttributeExpression logLevelExpression = new AttributeExpression(
+ new ClassExpression(classNode(PRIORITY_NAME)),
+ new ConstantExpression(methodName.toUpperCase(Locale.ENGLISH)));
+ ArgumentListExpression args = new ArgumentListExpression();
+ args.addExpression(logLevelExpression);
+ condition = new MethodCallExpression(logVariable, "isEnabledFor", args);
+ } else {
+ // log4j api is inconsistent, so trace requires special handling
+ condition = new MethodCallExpression(
+ logVariable,
+ "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+ ArgumentListExpression.EMPTY_ARGUMENTS);
+ }
+ condition.setImplicitThis(false);
+
+ return new TernaryExpression(
+ new BooleanExpression(condition),
+ originalExpression,
+ ConstantExpression.NULL);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Log4j2.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Log4j2.java b/src/main/groovy/groovy/util/logging/Log4j2.java
new file mode 100644
index 0000000..7aca5a5
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Log4j2.java
@@ -0,0 +1,105 @@
+/*
+ * 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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * Log4j2 logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameEnabled() {
+ * log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @since 2.2.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Log4j2 {
+ String value() default "log";
+ String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+ Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default Log4j2LoggingStrategy.class;
+
+ public static class Log4j2LoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+ private static final String LOGGER_NAME = "org.apache.logging.log4j.core.Logger";
+ private static final String LOG_MANAGER_NAME = "org.apache.logging.log4j.LogManager";
+
+ protected Log4j2LoggingStrategy(final GroovyClassLoader loader) {
+ super(loader);
+ }
+
+ public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+ return classNode.addField(logFieldName,
+ Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+ classNode(LOGGER_NAME),
+ new MethodCallExpression(
+ new ClassExpression(classNode(LOG_MANAGER_NAME)),
+ "getLogger",
+ new ConstantExpression(getCategoryName(classNode, categoryName))));
+ }
+
+ public boolean isLoggingMethod(String methodName) {
+ return methodName.matches("fatal|error|warn|info|debug|trace");
+ }
+
+ public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+ MethodCallExpression condition = new MethodCallExpression(
+ logVariable,
+ "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+ ArgumentListExpression.EMPTY_ARGUMENTS);
+ condition.setImplicitThis(false);
+
+ return new TernaryExpression(
+ new BooleanExpression(condition),
+ originalExpression,
+ ConstantExpression.NULL);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Slf4j.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Slf4j.java b/src/main/groovy/groovy/util/logging/Slf4j.java
new file mode 100644
index 0000000..0e866e4
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Slf4j.java
@@ -0,0 +1,108 @@
+/*
+ * 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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * LogBack logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameLoggable() {
+ * log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @author Hamlet D'Arcy
+ * @author Alberto Mijares
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Slf4j {
+ String value() default "log";
+ String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+ Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default Slf4jLoggingStrategy.class;
+
+ public static class Slf4jLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+ private static final String LOGGER_NAME = "org.slf4j.Logger";
+ private static final String FACTORY_NAME = "org.slf4j.LoggerFactory";
+
+ protected Slf4jLoggingStrategy(final GroovyClassLoader loader) {
+ super(loader);
+ }
+
+ public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+ return classNode.addField(logFieldName,
+ Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+ classNode(LOGGER_NAME),
+ new MethodCallExpression(
+ new ClassExpression(classNode(FACTORY_NAME)),
+ "getLogger",
+ new ConstantExpression(getCategoryName(classNode, categoryName))));
+ }
+
+ public boolean isLoggingMethod(String methodName) {
+ return methodName.matches("error|warn|info|debug|trace");
+ }
+
+ public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+ MethodCallExpression condition = new MethodCallExpression(
+ logVariable,
+ "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+ ArgumentListExpression.EMPTY_ARGUMENTS);
+ condition.setImplicitThis(false);
+
+ return new TernaryExpression(
+ new BooleanExpression(condition),
+ originalExpression,
+ ConstantExpression.NULL);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/package.html b/src/main/groovy/groovy/util/package.html
new file mode 100644
index 0000000..e7a2c5a
--- /dev/null
+++ b/src/main/groovy/groovy/util/package.html
@@ -0,0 +1,28 @@
+<!--
+
+ 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.
+
+-->
+<html>
+ <head>
+ <title>package groovy.util.*</title>
+ </head>
+ <body>
+ <p>Various Groovy utilities for working with nodes, builders, logging, JUnit test cases, text expressions, Ant tasks or JMX MBeans.</p>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/xml/QName.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/xml/QName.java b/src/main/groovy/groovy/xml/QName.java
new file mode 100644
index 0000000..06a733d
--- /dev/null
+++ b/src/main/groovy/groovy/xml/QName.java
@@ -0,0 +1,287 @@
+/*
+ * 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.xml;
+
+import java.io.Serializable;
+
+/**
+ * <code>QName</code> class represents the value of a qualified name
+ * as specified in <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML
+ * Schema Part2: Datatypes specification</a>.
+ * <p>
+ * The value of a QName contains a <b>namespaceURI</b>, a <b>localPart</b> and a <b>prefix</b>.
+ * The localPart provides the local part of the qualified name. The
+ * namespaceURI is a URI reference identifying the namespace.
+ */
+public class QName implements Serializable {
+ private static final long serialVersionUID = -9029109610006696081L;
+
+ /** comment/shared empty string */
+ private static final String EMPTY_STRING = "";
+
+ /** Field namespaceURI */
+ private String namespaceURI;
+
+ /** Field localPart */
+ private String localPart;
+
+ /** Field prefix */
+ private String prefix;
+
+ /**
+ * Constructor for the QName.
+ *
+ * @param localPart Local part of the QName
+ */
+ public QName(String localPart) {
+ this(EMPTY_STRING, localPart, EMPTY_STRING);
+ }
+
+ /**
+ * Constructor for the QName.
+ *
+ * @param namespaceURI Namespace URI for the QName
+ * @param localPart Local part of the QName.
+ */
+ public QName(String namespaceURI, String localPart) {
+ this(namespaceURI, localPart, EMPTY_STRING);
+ }
+
+ /**
+ * Constructor for the QName.
+ *
+ * @param namespaceURI Namespace URI for the QName
+ * @param localPart Local part of the QName.
+ * @param prefix Prefix of the QName.
+ */
+ public QName(String namespaceURI, String localPart, String prefix) {
+ this.namespaceURI = (namespaceURI == null)
+ ? EMPTY_STRING
+ : namespaceURI;
+ if (localPart == null) {
+ throw new IllegalArgumentException("invalid QName local part");
+ } else {
+ this.localPart = localPart;
+ }
+
+ if (prefix == null) {
+ throw new IllegalArgumentException("invalid QName prefix");
+ } else {
+ this.prefix = prefix;
+ }
+ }
+
+ /**
+ * Gets the Namespace URI for this QName
+ *
+ * @return Namespace URI
+ */
+ public String getNamespaceURI() {
+ return namespaceURI;
+ }
+
+ /**
+ * Gets the Local part for this QName
+ *
+ * @return Local part
+ */
+ public String getLocalPart() {
+ return localPart;
+ }
+
+ /**
+ * Gets the Prefix for this QName
+ *
+ * @return Prefix
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Returns the fully qualified name of this QName
+ *
+ * @return a string representation of the QName
+ */
+ public String getQualifiedName() {
+ return ((prefix.equals(EMPTY_STRING))
+ ? localPart
+ : prefix + ':' + localPart);
+ }
+
+ /**
+ * Returns a string representation of this QName
+ *
+ * @return a string representation of the QName
+ */
+ public String toString() {
+ return ((namespaceURI.equals(EMPTY_STRING))
+ ? localPart
+ : '{' + namespaceURI + '}' + localPart);
+ }
+
+ /**
+ * Tests this QName for equality with another object.
+ * <p>
+ * If the given object is not a QName or String equivalent or is null then this method
+ * returns <tt>false</tt>.
+ * <p>
+ * For two QNames to be considered equal requires that both
+ * localPart and namespaceURI must be equal. This method uses
+ * <code>String.equals</code> to check equality of localPart
+ * and namespaceURI. Any class that extends QName is required
+ * to satisfy this equality contract.
+ *
+ * If the supplied object is a String, then it is split in two on the last colon
+ * and the first half is compared against the prefix || namespaceURI
+ * and the second half is compared against the localPart
+ *
+ * i.e. assert new QName("namespace","localPart").equals("namespace:localPart")
+ *
+ * Intended Usage: for gpath accessors, e.g. root.'urn:mynamespace:node'
+ *
+ * Warning: this equivalence is not commutative,
+ * i.e. qname.equals(string) may be true/false but string.equals(qname) is always false
+ *
+ * <p>
+ * This method satisfies the general contract of the <code>Object.equals</code> method.
+ *
+ * @param o the reference object with which to compare
+ *
+ * @return <code>true</code> if the given object is identical to this
+ * QName: <code>false</code> otherwise.
+ */
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ if (o instanceof QName) {
+ final QName qName = (QName) o;
+ if (!namespaceURI.equals(qName.namespaceURI)) return false;
+ return localPart.equals(qName.localPart);
+
+ } else if (o instanceof String) {
+ final String string = (String)o;
+ if (string.length() == 0) return false;
+ int lastColonIndex = string.lastIndexOf(":");
+ if (lastColonIndex < 0 || lastColonIndex == string.length() - 1) return false;
+ final String stringPrefix = string.substring(0,lastColonIndex);
+ final String stringLocalPart = string.substring(lastColonIndex + 1);
+ if (stringPrefix.equals(prefix) || stringPrefix.equals(namespaceURI)) {
+ return localPart.equals(stringLocalPart);
+ }
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Tests if this QName matches another object.
+ * <p>
+ * If the given object is not a QName or String equivalent or is null then this method
+ * returns <tt>false</tt>.
+ * <p>
+ * For two QNames to be considered matching requires that both
+ * localPart and namespaceURI must be equal or one of them is a wildcard.
+ *
+ * If the supplied object is a String, then it is split in two on the last colon
+ * and the first half is matched against the prefix || namespaceURI
+ * and the second half is matched against the localPart
+ *
+ * @param o the reference object with which to compare
+ *
+ * @return <code>true</code> if the given object matches
+ * this QName: <code>false</code> otherwise.
+ */
+ public boolean matches(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ if (o instanceof QName) {
+ final QName qName = (QName) o;
+ if (!namespaceURI.equals(qName.namespaceURI) && !namespaceURI.equals("*") && !qName.namespaceURI.equals("*")) return false;
+ return localPart.equals(qName.localPart) || localPart.equals("*") || qName.localPart.equals("*");
+ } else if (o instanceof String) {
+ final String string = (String)o;
+ if (string.length() == 0) return false;
+ // try matching against 'prefix:localname'
+ int lastColonIndex = string.lastIndexOf(":");
+ if (lastColonIndex < 0 && prefix.length() == 0) return string.equals(localPart);
+ if (lastColonIndex < 0 || lastColonIndex == string.length() - 1) return false;
+ final String stringPrefix = string.substring(0,lastColonIndex);
+ final String stringLocalPart = string.substring(lastColonIndex + 1);
+ if (stringPrefix.equals(prefix) || stringPrefix.equals(namespaceURI) || stringPrefix.equals("*")) {
+ return localPart.equals(stringLocalPart) || stringLocalPart.equals("*");
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a QName holding the value of the specified String.
+ * <p>
+ * The string must be in the form returned by the QName.toString()
+ * method, i.e. "{namespaceURI}localPart", with the "{namespaceURI}"
+ * part being optional.
+ * <p>
+ * This method doesn't do a full validation of the resulting QName.
+ * In particular, it doesn't check that the resulting namespace URI
+ * is a legal URI (per RFC 2396 and RFC 2732), nor that the resulting
+ * local part is a legal NCName per the XML Namespaces specification.
+ *
+ * @param s the string to be parsed
+ * @throws java.lang.IllegalArgumentException If the specified String cannot be parsed as a QName
+ * @return QName corresponding to the given String
+ */
+ public static QName valueOf(String s) {
+
+ if ((s == null) || s.equals("")) {
+ throw new IllegalArgumentException("invalid QName literal");
+ }
+
+ if (s.charAt(0) == '{') {
+ int i = s.indexOf('}');
+
+ if (i == -1) {
+ throw new IllegalArgumentException("invalid QName literal");
+ }
+
+ if (i == s.length() - 1) {
+ throw new IllegalArgumentException("invalid QName literal");
+ } else {
+ return new QName(s.substring(1, i), s.substring(i + 1));
+ }
+ } else {
+ return new QName(s);
+ }
+ }
+
+ /**
+ * Returns a hash code value for this QName object. The hash code
+ * is based on both the localPart and namespaceURI parts of the
+ * QName. This method satisfies the general contract of the
+ * <code>Object.hashCode</code> method.
+ *
+ * @return a hash code value for this Qname object
+ */
+ public int hashCode() {
+ int result;
+ result = namespaceURI.hashCode();
+ result = 29 * result + localPart.hashCode();
+ return result;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/inspect/Inspector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/inspect/Inspector.java b/src/main/groovy/inspect/Inspector.java
deleted file mode 100644
index f0c94a7..0000000
--- a/src/main/groovy/inspect/Inspector.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * 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.inspect;
-
-import groovy.lang.GroovyObject;
-import groovy.lang.MetaClass;
-import groovy.lang.MetaMethod;
-import groovy.lang.PropertyValue;
-import org.codehaus.groovy.reflection.CachedClass;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
-
-import java.io.PrintStream;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * The Inspector provides a unified access to an object's
- * information that can be determined by introspection.
- *
- * @author Dierk Koenig
- */
-public class Inspector {
- protected Object objectUnderInspection;
-
- // Indexes to retrieve Class Property information
- public static final int CLASS_PACKAGE_IDX = 0;
- public static final int CLASS_CLASS_IDX = 1;
- public static final int CLASS_INTERFACE_IDX = 2;
- public static final int CLASS_SUPERCLASS_IDX = 3;
- public static final int CLASS_OTHER_IDX = 4;
-
- // Indexes to retrieve field and method information
- public static final int MEMBER_ORIGIN_IDX = 0;
- public static final int MEMBER_MODIFIER_IDX = 1;
- public static final int MEMBER_DECLARER_IDX = 2;
- public static final int MEMBER_TYPE_IDX = 3;
- public static final int MEMBER_NAME_IDX = 4;
- public static final int MEMBER_PARAMS_IDX = 5;
- public static final int MEMBER_VALUE_IDX = 5;
- public static final int MEMBER_EXCEPTIONS_IDX = 6;
-
- public static final String NOT_APPLICABLE = "n/a";
- public static final String GROOVY = "GROOVY";
- public static final String JAVA = "JAVA";
-
- /**
- * @param objectUnderInspection must not be null
- */
- public Inspector(Object objectUnderInspection) {
- if (null == objectUnderInspection) {
- throw new IllegalArgumentException("argument must not be null");
- }
- this.objectUnderInspection = objectUnderInspection;
- }
-
- /**
- * Get the Class Properties of the object under inspection.
- *
- * @return String array to be indexed by the CLASS_xxx_IDX constants
- */
- public String[] getClassProps() {
- String[] result = new String[CLASS_OTHER_IDX + 1];
- Package pack = getClassUnderInspection().getPackage();
- result[CLASS_PACKAGE_IDX] = "package " + ((pack == null) ? NOT_APPLICABLE : pack.getName());
- String modifiers = Modifier.toString(getClassUnderInspection().getModifiers());
- result[CLASS_CLASS_IDX] = modifiers + " class " + shortName(getClassUnderInspection());
- result[CLASS_INTERFACE_IDX] = "implements ";
- Class[] interfaces = getClassUnderInspection().getInterfaces();
- for (Class anInterface : interfaces) {
- result[CLASS_INTERFACE_IDX] += shortName(anInterface) + " ";
- }
- result[CLASS_SUPERCLASS_IDX] = "extends " + shortName(getClassUnderInspection().getSuperclass());
- result[CLASS_OTHER_IDX] = "is Primitive: " + getClassUnderInspection().isPrimitive()
- + ", is Array: " + getClassUnderInspection().isArray()
- + ", is Groovy: " + isGroovy();
- return result;
- }
-
- public boolean isGroovy() {
- return GroovyObject.class.isAssignableFrom(getClassUnderInspection());
- }
-
- /**
- * Gets the object being inspected.
- *
- * @return the object
- */
- public Object getObject() {
- return objectUnderInspection;
- }
-
- /**
- * Get info about usual Java instance and class Methods as well as Constructors.
- *
- * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
- */
- public Object[] getMethods() {
- Method[] methods = getClassUnderInspection().getMethods();
- Constructor[] ctors = getClassUnderInspection().getConstructors();
- Object[] result = new Object[methods.length + ctors.length];
- int resultIndex = 0;
- for (; resultIndex < methods.length; resultIndex++) {
- Method method = methods[resultIndex];
- result[resultIndex] = methodInfo(method);
- }
- for (int i = 0; i < ctors.length; i++, resultIndex++) {
- Constructor ctor = ctors[i];
- result[resultIndex] = methodInfo(ctor);
- }
- return result;
- }
-
- /**
- * Get info about instance and class Methods that are dynamically added through Groovy.
- *
- * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
- */
- public Object[] getMetaMethods() {
- MetaClass metaClass = InvokerHelper.getMetaClass(objectUnderInspection);
- List metaMethods = metaClass.getMetaMethods();
- Object[] result = new Object[metaMethods.size()];
- int i = 0;
- for (Iterator iter = metaMethods.iterator(); iter.hasNext(); i++) {
- MetaMethod metaMethod = (MetaMethod) iter.next();
- result[i] = methodInfo(metaMethod);
- }
- return result;
- }
-
- /**
- * Get info about usual Java public fields incl. constants.
- *
- * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
- */
- public Object[] getPublicFields() {
- Field[] fields = getClassUnderInspection().getFields();
- Object[] result = new Object[fields.length];
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- result[i] = fieldInfo(field);
- }
- return result;
- }
-
- /**
- * Get info about Properties (Java and Groovy alike).
- *
- * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
- */
- public Object[] getPropertyInfo() {
- List props = DefaultGroovyMethods.getMetaPropertyValues(objectUnderInspection);
- Object[] result = new Object[props.size()];
- int i = 0;
- for (Iterator iter = props.iterator(); iter.hasNext(); i++) {
- PropertyValue pv = (PropertyValue) iter.next();
- result[i] = fieldInfo(pv);
- }
- return result;
- }
-
- protected String[] fieldInfo(Field field) {
- String[] result = new String[MEMBER_VALUE_IDX + 1];
- result[MEMBER_ORIGIN_IDX] = JAVA;
- result[MEMBER_MODIFIER_IDX] = Modifier.toString(field.getModifiers());
- result[MEMBER_DECLARER_IDX] = shortName(field.getDeclaringClass());
- result[MEMBER_TYPE_IDX] = shortName(field.getType());
- result[MEMBER_NAME_IDX] = field.getName();
- try {
- result[MEMBER_VALUE_IDX] = InvokerHelper.inspect(field.get(objectUnderInspection));
- } catch (IllegalAccessException e) {
- result[MEMBER_VALUE_IDX] = NOT_APPLICABLE;
- }
- return withoutNulls(result);
- }
-
- protected String[] fieldInfo(PropertyValue pv) {
- String[] result = new String[MEMBER_VALUE_IDX + 1];
- result[MEMBER_ORIGIN_IDX] = GROOVY;
- result[MEMBER_MODIFIER_IDX] = "public";
- result[MEMBER_DECLARER_IDX] = NOT_APPLICABLE;
- result[MEMBER_TYPE_IDX] = shortName(pv.getType());
- result[MEMBER_NAME_IDX] = pv.getName();
- try {
- result[MEMBER_VALUE_IDX] = InvokerHelper.inspect(pv.getValue());
- } catch (Exception e) {
- result[MEMBER_VALUE_IDX] = NOT_APPLICABLE;
- }
- return withoutNulls(result);
- }
-
- protected Class getClassUnderInspection() {
- return objectUnderInspection.getClass();
- }
-
- public static String shortName(Class clazz) {
- if (null == clazz) return NOT_APPLICABLE;
- String className = clazz.getName();
- if (null == clazz.getPackage()) return className;
- String packageName = clazz.getPackage().getName();
- int offset = packageName.length();
- if (offset > 0) offset++;
- className = className.substring(offset);
- return className;
- }
-
- protected String[] methodInfo(Method method) {
- String[] result = new String[MEMBER_EXCEPTIONS_IDX + 1];
- int mod = method.getModifiers();
- result[MEMBER_ORIGIN_IDX] = JAVA;
- result[MEMBER_DECLARER_IDX] = shortName(method.getDeclaringClass());
- result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod);
- result[MEMBER_NAME_IDX] = method.getName();
- result[MEMBER_TYPE_IDX] = shortName(method.getReturnType());
- Class[] params = method.getParameterTypes();
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < params.length; j++) {
- sb.append(shortName(params[j]));
- if (j < (params.length - 1)) sb.append(", ");
- }
- result[MEMBER_PARAMS_IDX] = sb.toString();
- sb.setLength(0);
- Class[] exceptions = method.getExceptionTypes();
- for (int k = 0; k < exceptions.length; k++) {
- sb.append(shortName(exceptions[k]));
- if (k < (exceptions.length - 1)) sb.append(", ");
- }
- result[MEMBER_EXCEPTIONS_IDX] = sb.toString();
- return withoutNulls(result);
- }
-
- protected String[] methodInfo(Constructor ctor) {
- String[] result = new String[MEMBER_EXCEPTIONS_IDX + 1];
- int mod = ctor.getModifiers();
- result[MEMBER_ORIGIN_IDX] = JAVA;
- result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod);
- result[MEMBER_DECLARER_IDX] = shortName(ctor.getDeclaringClass());
- result[MEMBER_TYPE_IDX] = shortName(ctor.getDeclaringClass());
- result[MEMBER_NAME_IDX] = ctor.getName();
- Class[] params = ctor.getParameterTypes();
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < params.length; j++) {
- sb.append(shortName(params[j]));
- if (j < (params.length - 1)) sb.append(", ");
- }
- result[MEMBER_PARAMS_IDX] = sb.toString();
- sb.setLength(0);
- Class[] exceptions = ctor.getExceptionTypes();
- for (int k = 0; k < exceptions.length; k++) {
- sb.append(shortName(exceptions[k]));
- if (k < (exceptions.length - 1)) sb.append(", ");
- }
- result[MEMBER_EXCEPTIONS_IDX] = sb.toString();
- return withoutNulls(result);
- }
-
- protected String[] methodInfo(MetaMethod method) {
- String[] result = new String[MEMBER_EXCEPTIONS_IDX + 1];
- int mod = method.getModifiers();
- result[MEMBER_ORIGIN_IDX] = GROOVY;
- result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod);
- result[MEMBER_DECLARER_IDX] = shortName(method.getDeclaringClass().getTheClass());
- result[MEMBER_TYPE_IDX] = shortName(method.getReturnType());
- result[MEMBER_NAME_IDX] = method.getName();
- CachedClass[] params = method.getParameterTypes();
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < params.length; j++) {
- sb.append(shortName(params[j].getTheClass()));
- if (j < (params.length - 1)) sb.append(", ");
- }
- result[MEMBER_PARAMS_IDX] = sb.toString();
- result[MEMBER_EXCEPTIONS_IDX] = NOT_APPLICABLE; // no exception info for Groovy MetaMethods
- return withoutNulls(result);
- }
-
- protected String[] withoutNulls(String[] toNormalize) {
- for (int i = 0; i < toNormalize.length; i++) {
- String s = toNormalize[i];
- if (null == s) toNormalize[i] = NOT_APPLICABLE;
- }
- return toNormalize;
- }
-
- public static void print(Object[] memberInfo) {
- print(System.out, memberInfo);
- }
-
- static void print(final PrintStream out, Object[] memberInfo) {
- for (int i = 0; i < memberInfo.length; i++) {
- String[] metaMethod = (String[]) memberInfo[i];
- out.print(i + ":\t");
- for (String s : metaMethod) {
- out.print(s + " ");
- }
- out.println("");
- }
- }
-
- public static Collection sort(List<Object> memberInfo) {
- Collections.sort(memberInfo, new MemberComparator());
- return memberInfo;
- }
-
- public static class MemberComparator implements Comparator<Object>, Serializable {
- private static final long serialVersionUID = -7691851726606749541L;
-
- public int compare(Object a, Object b) {
- String[] aStr = (String[]) a;
- String[] bStr = (String[]) b;
- int result = aStr[Inspector.MEMBER_NAME_IDX].compareTo(bStr[Inspector.MEMBER_NAME_IDX]);
- if (0 != result) return result;
- result = aStr[Inspector.MEMBER_TYPE_IDX].compareTo(bStr[Inspector.MEMBER_TYPE_IDX]);
- if (0 != result) return result;
- result = aStr[Inspector.MEMBER_PARAMS_IDX].compareTo(bStr[Inspector.MEMBER_PARAMS_IDX]);
- if (0 != result) return result;
- result = aStr[Inspector.MEMBER_DECLARER_IDX].compareTo(bStr[Inspector.MEMBER_DECLARER_IDX]);
- if (0 != result) return result;
- result = aStr[Inspector.MEMBER_MODIFIER_IDX].compareTo(bStr[Inspector.MEMBER_MODIFIER_IDX]);
- if (0 != result) return result;
- result = aStr[Inspector.MEMBER_ORIGIN_IDX].compareTo(bStr[Inspector.MEMBER_ORIGIN_IDX]);
- return result;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/inspect/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/inspect/package.html b/src/main/groovy/inspect/package.html
deleted file mode 100644
index 6d80c2b..0000000
--- a/src/main/groovy/inspect/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-
- 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.
-
--->
-<html>
- <head>
- <title>package groovy.inspect.*</title>
- </head>
- <body>
- <p>Classes for inspecting object properties through introspection.</p>
- </body>
-</html>
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/io/EncodingAwareBufferedWriter.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/io/EncodingAwareBufferedWriter.java b/src/main/groovy/io/EncodingAwareBufferedWriter.java
deleted file mode 100644
index 2faaaeb..0000000
--- a/src/main/groovy/io/EncodingAwareBufferedWriter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.io;
-
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-
-/**
- * A buffered writer only for OutputStreamWriter that is aware of
- * the encoding of the OutputStreamWriter.
- *
- * @author Paul King
- */
-
-public class EncodingAwareBufferedWriter extends BufferedWriter {
- private final OutputStreamWriter out;
- public EncodingAwareBufferedWriter(OutputStreamWriter out) {
- super(out);
- this.out = out;
- }
-
- /**
- * The encoding as returned by the underlying OutputStreamWriter. Can be the historical name.
- *
- * @return the encoding
- * @see java.io.OutputStreamWriter#getEncoding()
- */
- public String getEncoding() {
- return out.getEncoding();
- }
-
- /**
- * The encoding as returned by the underlying OutputStreamWriter. Will be the preferred name.
- *
- * @return the encoding
- * @see java.io.OutputStreamWriter#getEncoding()
- */
- public String getNormalizedEncoding() {
- return Charset.forName(getEncoding()).name();
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/io/FileType.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/io/FileType.java b/src/main/groovy/io/FileType.java
deleted file mode 100644
index 18727e4..0000000
--- a/src/main/groovy/io/FileType.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.io;
-
-/**
- * Represents particular files of interest.
- */
-public enum FileType {
- /** Represents normal files */
- FILES,
- /** Represents directories */
- DIRECTORIES,
- /** Represents both normal files and directories */
- ANY
-}