http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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 + */ [email protected] +@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/d638ca43/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 + */ [email protected] +@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/d638ca43/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 + */ [email protected] +@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/d638ca43/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 + */ [email protected] +@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/d638ca43/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 + */ [email protected] +@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/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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/d638ca43/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 -}
