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 00:56:00 UTC
[03/49] groovy git commit: Move source files to proper packages
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/GroovyCollections.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/GroovyCollections.java b/src/main/groovy/util/GroovyCollections.java
deleted file mode 100644
index dff062d..0000000
--- a/src/main/groovy/util/GroovyCollections.java
+++ /dev/null
@@ -1,293 +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.util;
-
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A Collections utility class
- *
- * @author Paul King
- * @author Jim White
- */
-public class GroovyCollections {
- /**
- * Finds all combinations of items from the given collections.
- *
- * @param collections the given collections
- * @return a List of the combinations found
- * @see #combinations(Collection)
- */
- public static List combinations(Object[] collections) {
- return combinations((Iterable)Arrays.asList(collections));
- }
-
- /**
- * Finds all non-null subsequences of a list.
- * E.g. <code>subsequences([1, 2, 3])</code> would be:
- * [[1, 2, 3], [1, 3], [2, 3], [1, 2], [1], [2], [3]]
- *
- * @param items the List of items
- * @return the subsequences from items
- */
- public static <T> Set<List<T>> subsequences(List<T> items) {
- // items.inject([]){ ss, h -> ss.collect { it + [h] } + ss + [[h]] }
- Set<List<T>> ans = new HashSet<List<T>>();
- for (T h : items) {
- Set<List<T>> next = new HashSet<List<T>>();
- for (List<T> it : ans) {
- List<T> sublist = new ArrayList<T>(it);
- sublist.add(h);
- next.add(sublist);
- }
- next.addAll(ans);
- List<T> hlist = new ArrayList<T>();
- hlist.add(h);
- next.add(hlist);
- ans = next;
- }
- return ans;
- }
-
- /**
- * @param collections the given collections
- * @deprecated use combinations(Iterable)
- */
- @Deprecated
- public static List combinations(Collection collections) {
- return combinations((Iterable)collections);
- }
-
- /**
- * Finds all combinations of items from the given Iterable aggregate of collections.
- * So, <code>combinations([[true, false], [true, false]])</code>
- * is <code>[[true, true], [false, true], [true, false], [false, false]]</code>
- * and <code>combinations([['a', 'b'],[1, 2, 3]])</code>
- * is <code>[['a', 1], ['b', 1], ['a', 2], ['b', 2], ['a', 3], ['b', 3]]</code>.
- * If a non-collection item is given, it is treated as a singleton collection,
- * i.e. <code>combinations([[1, 2], 'x'])</code> is <code>[[1, 'x'], [2, 'x']]</code>.
- *
- * @param collections the Iterable of given collections
- * @return a List of the combinations found
- * @since 2.2.0
- */
- public static List combinations(Iterable collections) {
- List collectedCombos = new ArrayList();
- for (Object collection : collections) {
- Iterable items = DefaultTypeTransformation.asCollection(collection);
- if (collectedCombos.isEmpty()) {
- for (Object item : items) {
- List l = new ArrayList();
- l.add(item);
- collectedCombos.add(l);
- }
- } else {
- List savedCombos = new ArrayList(collectedCombos);
- List newCombos = new ArrayList();
- for (Object value : items) {
- for (Object savedCombo : savedCombos) {
- List oldList = new ArrayList((List) savedCombo);
- oldList.add(value);
- newCombos.add(oldList);
- }
- }
- collectedCombos = newCombos;
- }
- }
- return collectedCombos;
- }
-
- public static <T> List<List<T>> inits(Iterable<T> collections) {
- List<T> copy = DefaultGroovyMethods.toList(collections);
- List<List<T>> result = new ArrayList<List<T>>();
- for (int i = copy.size(); i >= 0; i--) {
- List<T> next = copy.subList(0, i);
- result.add(next);
- }
- return result;
- }
-
- public static <T> List<List<T>> tails(Iterable<T> collections) {
- List<T> copy = DefaultGroovyMethods.toList(collections);
- List<List<T>> result = new ArrayList<List<T>>();
- for (int i = 0; i <= copy.size(); i++) {
- List<T> next = copy.subList(i, copy.size());
- result.add(next);
- }
- return result;
- }
-
- /**
- * Transposes an array of lists.
- *
- * @param lists the given lists
- * @return a List of the transposed lists
- * @see #transpose(List)
- */
- public static List transpose(Object[] lists) {
- return transpose(Arrays.asList(lists));
- }
-
- /**
- * Transposes the given lists.
- * So, <code>transpose([['a', 'b'], [1, 2]])</code>
- * is <code>[['a', 1], ['b', 2]]</code> and
- * <code>transpose([['a', 'b', 'c']])</code>
- * is <code>[['a'], ['b'], ['c']]</code>.
- *
- * @param lists the given lists
- * @return a List of the transposed lists
- */
- public static List transpose(List lists) {
- List result = new ArrayList();
- if (lists.isEmpty()) return result;
- int minSize = Integer.MAX_VALUE;
- for (Object listLike : lists) {
- List list = (List) DefaultTypeTransformation.castToType(listLike, List.class);
- if (list.size() < minSize) minSize = list.size();
- }
- if (minSize == 0) return result;
- for (int i = 0; i < minSize; i++) {
- result.add(new ArrayList());
- }
- for (Object listLike : lists) {
- List list = (List) DefaultTypeTransformation.castToType(listLike, List.class);
- for (int i = 0; i < minSize; i++) {
- List resultList = (List) result.get(i);
- resultList.add(list.get(i));
- }
- }
- return result;
- }
-
- /**
- * Selects the minimum value found in an array of items, so
- * min([2, 4, 6] as Object[]) == 2.
- *
- * @param items an array of items
- * @return the minimum value
- */
- public static <T> T min(T[] items) {
- return min((Iterable<T>)Arrays.asList(items));
- }
-
- /**
- * @deprecated use min(Iterable)
- */
- @Deprecated
- public static <T> T min(Collection<T> items) {
- return min((Iterable<T>)items);
- }
-
- /**
- * Selects the minimum value found in an Iterable of items.
- *
- * @param items an Iterable
- * @return the minimum value
- * @since 2.2.0
- */
- public static <T> T min(Iterable<T> items) {
- T answer = null;
- for (T value : items) {
- if (value != null) {
- if (answer == null || ScriptBytecodeAdapter.compareLessThan(value, answer)) {
- answer = value;
- }
- }
- }
- return answer;
- }
-
- /**
- * Selects the maximum value found in an array of items, so
- * min([2, 4, 6] as Object[]) == 6.
- *
- * @param items an array of items
- * @return the maximum value
- */
- public static <T> T max(T[] items) {
- return max((Iterable<T>)Arrays.asList(items));
- }
-
- /**
- * @deprecated use max(Iterable)
- */
- @Deprecated
- public static <T> T max(Collection<T> items) {
- return max((Iterable<T>)items);
- }
-
- /**
- * Selects the maximum value found in an Iterable.
- *
- * @param items a Collection
- * @return the maximum value
- * @since 2.2.0
- */
- public static <T> T max(Iterable<T> items) {
- T answer = null;
- for (T value : items) {
- if (value != null) {
- if (answer == null || ScriptBytecodeAdapter.compareGreaterThan(value, answer)) {
- answer = value;
- }
- }
- }
- return answer;
- }
-
- /**
- * Sums all the items from an array of items.
- *
- * @param items an array of items
- * @return the sum of the items
- */
- public static Object sum(Object[] items) {
- return sum((Iterable)Arrays.asList(items));
- }
-
- /**
- * @deprecated use sum(Iterable)
- */
- @Deprecated
- public static Object sum(Collection items) {
- return sum((Iterable)items);
- }
-
- /**
- * Sums all the given items.
- *
- * @param items an Iterable of items
- * @return the sum of the item
- * @since 2.2.0
- */
- public static Object sum(Iterable items) {
- return DefaultGroovyMethods.sum(items);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/GroovyScriptEngine.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/GroovyScriptEngine.java b/src/main/groovy/util/GroovyScriptEngine.java
deleted file mode 100644
index 92e2486..0000000
--- a/src/main/groovy/util/GroovyScriptEngine.java
+++ /dev/null
@@ -1,694 +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.util;
-
-import groovy.lang.Binding;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyCodeSource;
-import groovy.lang.GroovyResourceLoader;
-import groovy.lang.Script;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.classgen.GeneratorContext;
-import org.codehaus.groovy.control.ClassNodeResolver;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.control.Phases;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.customizers.CompilationCustomizer;
-import org.codehaus.groovy.runtime.IOGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.tools.gse.DependencyTracker;
-import org.codehaus.groovy.tools.gse.StringSetMap;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.ref.WeakReference;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Specific script engine able to reload modified scripts as well as dealing properly
- * with dependent scripts.
- *
- * @author sam
- * @author Marc Palmer
- * @author Guillaume Laforge
- * @author Jochen Theodorou
- * @author Mattias Reichel
- */
-public class GroovyScriptEngine implements ResourceConnector {
- private static final ClassLoader CL_STUB = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return new ClassLoader() {};
- }
- });
-
- private static final URL[] EMPTY_URL_ARRAY = new URL[0];
-
- private static class LocalData {
- CompilationUnit cu;
- final StringSetMap dependencyCache = new StringSetMap();
- final Map<String, String> precompiledEntries = new HashMap<String, String>();
- }
-
- private static WeakReference<ThreadLocal<LocalData>> localData = new WeakReference<ThreadLocal<LocalData>>(null);
-
- private static synchronized ThreadLocal<LocalData> getLocalData() {
- ThreadLocal<LocalData> local = localData.get();
- if (local != null) return local;
- local = new ThreadLocal<LocalData>();
- localData = new WeakReference<ThreadLocal<LocalData>>(local);
- return local;
- }
-
- private final URL[] roots;
- private final ResourceConnector rc;
- private final ClassLoader parentLoader;
- private GroovyClassLoader groovyLoader;
- private final Map<String, ScriptCacheEntry> scriptCache = new ConcurrentHashMap<String, ScriptCacheEntry>();
- private CompilerConfiguration config;
-
- {
- config = new CompilerConfiguration(CompilerConfiguration.DEFAULT);
- config.setSourceEncoding(CompilerConfiguration.DEFAULT_SOURCE_ENCODING);
- }
-
-
- //TODO: more finals?
-
- private static class ScriptCacheEntry {
- private final Class scriptClass;
- private final long lastModified, lastCheck;
- private final Set<String> dependencies;
- private final boolean sourceNewer;
-
- public ScriptCacheEntry(Class clazz, long modified, long lastCheck, Set<String> depend, boolean sourceNewer) {
- this.scriptClass = clazz;
- this.lastModified = modified;
- this.lastCheck = lastCheck;
- this.dependencies = depend;
- this.sourceNewer = sourceNewer;
- }
-
- public ScriptCacheEntry(ScriptCacheEntry old, long lastCheck, boolean sourceNewer) {
- this(old.scriptClass, old.lastModified, lastCheck, old.dependencies, sourceNewer);
- }
- }
-
- private class ScriptClassLoader extends GroovyClassLoader {
-
-
- public ScriptClassLoader(GroovyClassLoader loader) {
- super(loader);
- }
-
- public ScriptClassLoader(ClassLoader loader, CompilerConfiguration config) {
- super(loader, config, false);
- setResLoader();
- }
-
- private void setResLoader() {
- final GroovyResourceLoader rl = getResourceLoader();
- setResourceLoader(new GroovyResourceLoader() {
- public URL loadGroovySource(String className) throws MalformedURLException {
- String filename;
- for (String extension : getConfig().getScriptExtensions()) {
- filename = className.replace('.', File.separatorChar) + "." + extension;
- try {
- URLConnection dependentScriptConn = rc.getResourceConnection(filename);
- return dependentScriptConn.getURL();
- } catch (ResourceException e) {
- //TODO: maybe do something here?
- }
- }
- return rl.loadGroovySource(className);
- }
- });
- }
-
- @Override
- protected CompilationUnit createCompilationUnit(CompilerConfiguration configuration, CodeSource source) {
- CompilationUnit cu = super.createCompilationUnit(configuration, source);
- LocalData local = getLocalData().get();
- local.cu = cu;
- final StringSetMap cache = local.dependencyCache;
- final Map<String, String> precompiledEntries = local.precompiledEntries;
-
- // "." is used to transfer compilation dependencies, which will be
- // recollected later during compilation
- for (String depSourcePath : cache.get(".")) {
- try {
- cache.get(depSourcePath);
- cu.addSource(getResourceConnection(depSourcePath).getURL());
- } catch (ResourceException e) {
- /* ignore */
- }
- }
-
- // remove all old entries including the "." entry
- cache.clear();
-
- cu.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, GeneratorContext context, ClassNode classNode)
- throws CompilationFailedException {
- // GROOVY-4013: If it is an inner class, tracking its dependencies doesn't really
- // serve any purpose and also interferes with the caching done to track dependencies
- if (classNode instanceof InnerClassNode) return;
- DependencyTracker dt = new DependencyTracker(source, cache, precompiledEntries);
- dt.visitClass(classNode);
- }
- }, Phases.CLASS_GENERATION);
-
- cu.setClassNodeResolver(new ClassNodeResolver() {
- @Override
- public LookupResult findClassNode(String origName, CompilationUnit compilationUnit) {
- CompilerConfiguration cc = compilationUnit.getConfiguration();
- String name = origName.replace('.', '/');
- for (String ext : cc.getScriptExtensions()) {
- try {
- String finalName = name + "." + ext;
- URLConnection conn = rc.getResourceConnection(finalName);
- URL url = conn.getURL();
- String path = url.toExternalForm();
- ScriptCacheEntry entry = scriptCache.get(path);
- Class clazz = null;
- if (entry != null) clazz = entry.scriptClass;
- if (GroovyScriptEngine.this.isSourceNewer(entry)) {
- try {
- SourceUnit su = compilationUnit.addSource(url);
- return new LookupResult(su, null);
- } finally {
- forceClose(conn);
- }
- } else {
- precompiledEntries.put(origName, path);
- }
- if (clazz != null) {
- ClassNode cn = new ClassNode(clazz);
- return new LookupResult(null, cn);
- }
- } catch (ResourceException re) {
- // skip
- }
- }
- return super.findClassNode(origName, compilationUnit);
- }
- });
-
- return cu;
- }
-
- @Override
- public Class parseClass(GroovyCodeSource codeSource, boolean shouldCacheSource) throws CompilationFailedException {
- synchronized (sourceCache) {
- return doParseClass(codeSource);
- }
- }
-
- private Class<?> doParseClass(GroovyCodeSource codeSource) {
- // local is kept as hard reference to avoid garbage collection
- ThreadLocal<LocalData> localTh = getLocalData();
- LocalData localData = new LocalData();
- localTh.set(localData);
- StringSetMap cache = localData.dependencyCache;
- Class<?> answer = null;
- try {
- updateLocalDependencyCache(codeSource, localData);
- answer = super.parseClass(codeSource, false);
- updateScriptCache(localData);
- } finally {
- cache.clear();
- localTh.remove();
- }
- return answer;
- }
-
- private void updateLocalDependencyCache(GroovyCodeSource codeSource, LocalData localData) {
- // we put the old dependencies into local cache so createCompilationUnit
- // can pick it up. We put that entry under the name "."
- ScriptCacheEntry origEntry = scriptCache.get(codeSource.getName());
- Set<String> origDep = null;
- if (origEntry != null) origDep = origEntry.dependencies;
- if (origDep != null) {
- Set<String> newDep = new HashSet<String>(origDep.size());
- for (String depName : origDep) {
- ScriptCacheEntry dep = scriptCache.get(depName);
- try {
- if (origEntry == dep || GroovyScriptEngine.this.isSourceNewer(dep)) {
- newDep.add(depName);
- }
- } catch (ResourceException re) {
-
- }
- }
- StringSetMap cache = localData.dependencyCache;
- cache.put(".", newDep);
- }
- }
-
- private void updateScriptCache(LocalData localData) {
- StringSetMap cache = localData.dependencyCache;
- cache.makeTransitiveHull();
- long time = getCurrentTime();
- Set<String> entryNames = new HashSet<String>();
- for (Map.Entry<String, Set<String>> entry : cache.entrySet()) {
- String className = entry.getKey();
- Class clazz = getClassCacheEntry(className);
- if (clazz == null) continue;
-
- String entryName = getPath(clazz, localData.precompiledEntries);
- if (entryNames.contains(entryName)) continue;
- entryNames.add(entryName);
- Set<String> value = convertToPaths(entry.getValue(), localData.precompiledEntries);
- long lastModified;
- try {
- lastModified = getLastModified(entryName);
- } catch (ResourceException e) {
- lastModified = time;
- }
- ScriptCacheEntry cacheEntry = new ScriptCacheEntry(clazz, lastModified, time, value, false);
- scriptCache.put(entryName, cacheEntry);
- }
- }
-
- private String getPath(Class clazz, Map<String, String> precompiledEntries) {
- CompilationUnit cu = getLocalData().get().cu;
- String name = clazz.getName();
- ClassNode classNode = cu.getClassNode(name);
- if (classNode == null) {
- // this is a precompiled class!
- String path = precompiledEntries.get(name);
- if (path == null) throw new GroovyBugError("Precompiled class " + name + " should be available in precompiled entries map, but was not.");
- return path;
- } else {
- return classNode.getModule().getContext().getName();
- }
- }
-
- private Set<String> convertToPaths(Set<String> orig, Map<String, String> precompiledEntries) {
- Set<String> ret = new HashSet<String>();
- for (String className : orig) {
- Class clazz = getClassCacheEntry(className);
- if (clazz == null) continue;
- ret.add(getPath(clazz, precompiledEntries));
- }
- return ret;
- }
- }
-
- /**
- * Simple testing harness for the GSE. Enter script roots as arguments and
- * then input script names to run them.
- *
- * @param urls an array of URLs
- * @throws Exception if something goes wrong
- */
- public static void main(String[] urls) throws Exception {
- GroovyScriptEngine gse = new GroovyScriptEngine(urls);
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- String line;
- while (true) {
- System.out.print("groovy> ");
- if ((line = br.readLine()) == null || line.equals("quit")) {
- break;
- }
- try {
- System.out.println(gse.run(line, new Binding()));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- /**
- * Initialize a new GroovyClassLoader with a default or
- * constructor-supplied parentClassLoader.
- *
- * @return the parent classloader used to load scripts
- */
- private GroovyClassLoader initGroovyLoader() {
- GroovyClassLoader groovyClassLoader =
- AccessController.doPrivileged(new PrivilegedAction<ScriptClassLoader>() {
- public ScriptClassLoader run() {
- if (parentLoader instanceof GroovyClassLoader) {
- return new ScriptClassLoader((GroovyClassLoader) parentLoader);
- } else {
- return new ScriptClassLoader(parentLoader, config);
- }
- }
- });
- for (URL root : roots) groovyClassLoader.addURL(root);
- return groovyClassLoader;
- }
-
- /**
- * Get a resource connection as a <code>URLConnection</code> to retrieve a script
- * from the <code>ResourceConnector</code>.
- *
- * @param resourceName name of the resource to be retrieved
- * @return a URLConnection to the resource
- * @throws ResourceException
- */
- public URLConnection getResourceConnection(String resourceName) throws ResourceException {
- // Get the URLConnection
- URLConnection groovyScriptConn = null;
-
- ResourceException se = null;
- for (URL root : roots) {
- URL scriptURL = null;
- try {
- scriptURL = new URL(root, resourceName);
- groovyScriptConn = openConnection(scriptURL);
-
- break; // Now this is a bit unusual
- } catch (MalformedURLException e) {
- String message = "Malformed URL: " + root + ", " + resourceName;
- if (se == null) {
- se = new ResourceException(message);
- } else {
- se = new ResourceException(message, se);
- }
- } catch (IOException e1) {
- String message = "Cannot open URL: " + root + resourceName;
- groovyScriptConn = null;
- if (se == null) {
- se = new ResourceException(message);
- } else {
- se = new ResourceException(message, se);
- }
- }
- }
-
- if (se == null) se = new ResourceException("No resource for " + resourceName + " was found");
-
- // If we didn't find anything, report on all the exceptions that occurred.
- if (groovyScriptConn == null) throw se;
- return groovyScriptConn;
- }
-
- private static URLConnection openConnection(URL scriptURL) throws IOException {
- URLConnection urlConnection = scriptURL.openConnection();
- verifyInputStream(urlConnection);
-
- return scriptURL.openConnection();
- }
-
- /**
- * This method closes a {@link URLConnection} by getting its {@link InputStream} and calling the
- * {@link InputStream#close()} method on it. The {@link URLConnection} doesn't have a close() method
- * and relies on garbage collection to close the underlying connection to the file.
- * Relying on garbage collection could lead to the application exhausting the number of files the
- * user is allowed to have open at any one point in time and cause the application to crash
- * ({@link java.io.FileNotFoundException} (Too many open files)).
- * Hence the need for this method to explicitly close the underlying connection to the file.
- *
- * @param urlConnection the {@link URLConnection} to be "closed" to close the underlying file descriptors.
- */
- private static void forceClose(URLConnection urlConnection) {
- if (urlConnection != null) {
- // We need to get the input stream and close it to force the open
- // file descriptor to be released. Otherwise, we will reach the limit
- // for number of files open at one time.
-
- try {
- verifyInputStream(urlConnection);
- } catch (Exception e) {
- // Do nothing: We were not going to use it anyway.
- }
- }
- }
-
- private static void verifyInputStream(URLConnection urlConnection) throws IOException {
- InputStream in = null;
- try {
- in = urlConnection.getInputStream();
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ignore) {
- }
- }
- }
- }
-
- /**
- * The groovy script engine will run groovy scripts and reload them and
- * their dependencies when they are modified. This is useful for embedding
- * groovy in other containers like games and application servers.
- *
- * @param roots This an array of URLs where Groovy scripts will be stored. They should
- * be laid out using their package structure like Java classes
- */
- private GroovyScriptEngine(URL[] roots, ClassLoader parent, ResourceConnector rc) {
- if (roots == null) roots = EMPTY_URL_ARRAY;
- this.roots = roots;
- if (rc == null) rc = this;
- this.rc = rc;
- if (parent == CL_STUB) parent = this.getClass().getClassLoader();
- this.parentLoader = parent;
- this.groovyLoader = initGroovyLoader();
- }
-
- public GroovyScriptEngine(URL[] roots) {
- this(roots, CL_STUB, null);
- }
-
- public GroovyScriptEngine(URL[] roots, ClassLoader parentClassLoader) {
- this(roots, parentClassLoader, null);
- }
-
- public GroovyScriptEngine(String[] urls) throws IOException {
- this(createRoots(urls), CL_STUB, null);
- }
-
- private static URL[] createRoots(String[] urls) throws MalformedURLException {
- if (urls == null) return null;
- URL[] roots = new URL[urls.length];
- for (int i = 0; i < roots.length; i++) {
- if (urls[i].contains("://")) {
- roots[i] = new URL(urls[i]);
- } else {
- roots[i] = new File(urls[i]).toURI().toURL();
- }
- }
- return roots;
- }
-
- public GroovyScriptEngine(String[] urls, ClassLoader parentClassLoader) throws IOException {
- this(createRoots(urls), parentClassLoader, null);
- }
-
- public GroovyScriptEngine(String url) throws IOException {
- this(new String[]{url});
- }
-
- public GroovyScriptEngine(String url, ClassLoader parentClassLoader) throws IOException {
- this(new String[]{url}, parentClassLoader);
- }
-
- public GroovyScriptEngine(ResourceConnector rc) {
- this(null, CL_STUB, rc);
- }
-
- public GroovyScriptEngine(ResourceConnector rc, ClassLoader parentClassLoader) {
- this(null, parentClassLoader, rc);
- }
-
- /**
- * Get the <code>ClassLoader</code> that will serve as the parent ClassLoader of the
- * {@link GroovyClassLoader} in which scripts will be executed. By default, this is the
- * ClassLoader that loaded the <code>GroovyScriptEngine</code> class.
- *
- * @return the parent classloader used to load scripts
- */
- public ClassLoader getParentClassLoader() {
- return parentLoader;
- }
-
- /**
- * Get the class of the scriptName in question, so that you can instantiate
- * Groovy objects with caching and reloading.
- *
- * @param scriptName resource name pointing to the script
- * @return the loaded scriptName as a compiled class
- * @throws ResourceException if there is a problem accessing the script
- * @throws ScriptException if there is a problem parsing the script
- */
- public Class loadScriptByName(String scriptName) throws ResourceException, ScriptException {
- URLConnection conn = rc.getResourceConnection(scriptName);
- String path = conn.getURL().toExternalForm();
- ScriptCacheEntry entry = scriptCache.get(path);
- Class clazz = null;
- if (entry != null) clazz = entry.scriptClass;
- try {
- if (isSourceNewer(entry)) {
- try {
- String encoding = conn.getContentEncoding() != null ? conn.getContentEncoding() : config.getSourceEncoding();
- String content = IOGroovyMethods.getText(conn.getInputStream(), encoding);
- clazz = groovyLoader.parseClass(content, path);
- } catch (IOException e) {
- throw new ResourceException(e);
- }
- }
- } finally {
- forceClose(conn);
- }
- return clazz;
- }
-
- /**
- * Run a script identified by name with a single argument.
- *
- * @param scriptName name of the script to run
- * @param argument a single argument passed as a variable named <code>arg</code> in the binding
- * @return a <code>toString()</code> representation of the result of the execution of the script
- * @throws ResourceException if there is a problem accessing the script
- * @throws ScriptException if there is a problem parsing the script
- */
- public String run(String scriptName, String argument) throws ResourceException, ScriptException {
- Binding binding = new Binding();
- binding.setVariable("arg", argument);
- Object result = run(scriptName, binding);
- return result == null ? "" : result.toString();
- }
-
- /**
- * Run a script identified by name with a given binding.
- *
- * @param scriptName name of the script to run
- * @param binding the binding to pass to the script
- * @return an object
- * @throws ResourceException if there is a problem accessing the script
- * @throws ScriptException if there is a problem parsing the script
- */
- public Object run(String scriptName, Binding binding) throws ResourceException, ScriptException {
- return createScript(scriptName, binding).run();
- }
-
- /**
- * Creates a Script with a given scriptName and binding.
- *
- * @param scriptName name of the script to run
- * @param binding the binding to pass to the script
- * @return the script object
- * @throws ResourceException if there is a problem accessing the script
- * @throws ScriptException if there is a problem parsing the script
- */
- public Script createScript(String scriptName, Binding binding) throws ResourceException, ScriptException {
- return InvokerHelper.createScript(loadScriptByName(scriptName), binding);
- }
-
- private long getLastModified(String scriptName) throws ResourceException {
- URLConnection conn = rc.getResourceConnection(scriptName);
- long lastMod = 0;
- try {
- lastMod = conn.getLastModified();
- } finally {
- // getResourceConnection() opening the inputstream, let's ensure all streams are closed
- forceClose(conn);
- }
- return lastMod;
- }
-
- protected boolean isSourceNewer(ScriptCacheEntry entry) throws ResourceException {
- if (entry == null) return true;
-
- long mainEntryLastCheck = entry.lastCheck;
- long now = 0;
-
- boolean returnValue = false;
- for (String scriptName : entry.dependencies) {
- ScriptCacheEntry depEntry = scriptCache.get(scriptName);
- if (depEntry.sourceNewer) return true;
-
- // check if maybe dependency was recompiled, but this one here not
- if (mainEntryLastCheck < depEntry.lastModified) {
- returnValue = true;
- continue;
- }
-
- if (now == 0) now = getCurrentTime();
- long nextSourceCheck = depEntry.lastCheck + config.getMinimumRecompilationInterval();
- if (nextSourceCheck > now) continue;
-
- long lastMod = getLastModified(scriptName);
- if (depEntry.lastModified < lastMod) {
- depEntry = new ScriptCacheEntry(depEntry, lastMod, true);
- scriptCache.put(scriptName, depEntry);
- returnValue = true;
- } else {
- depEntry = new ScriptCacheEntry(depEntry, now, false);
- scriptCache.put(scriptName, depEntry);
- }
- }
-
- return returnValue;
- }
-
- /**
- * Returns the GroovyClassLoader associated with this script engine instance.
- * Useful if you need to pass the class loader to another library.
- *
- * @return the GroovyClassLoader
- */
- public GroovyClassLoader getGroovyClassLoader() {
- return groovyLoader;
- }
-
- /**
- * @return a non null compiler configuration
- */
- public CompilerConfiguration getConfig() {
- return config;
- }
-
- /**
- * sets a compiler configuration
- *
- * @param config - the compiler configuration
- * @throws NullPointerException if config is null
- */
- public void setConfig(CompilerConfiguration config) {
- if (config == null) throw new NullPointerException("configuration cannot be null");
- this.config = config;
- this.groovyLoader = initGroovyLoader();
- }
-
- protected long getCurrentTime() {
- return System.currentTimeMillis();
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/IFileNameFinder.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/IFileNameFinder.java b/src/main/groovy/util/IFileNameFinder.java
deleted file mode 100644
index 35e9012..0000000
--- a/src/main/groovy/util/IFileNameFinder.java
+++ /dev/null
@@ -1,26 +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.util;
-
-import java.util.List;
-
-public interface IFileNameFinder {
- List<String> getFileNames(String basedir, String pattern);
- List<String> getFileNames(String basedir, String pattern, String excludesPattern);
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/IndentPrinter.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/IndentPrinter.java b/src/main/groovy/util/IndentPrinter.java
deleted file mode 100644
index df3d8c2..0000000
--- a/src/main/groovy/util/IndentPrinter.java
+++ /dev/null
@@ -1,234 +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.util;
-
-import groovy.lang.GroovyRuntimeException;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Writer;
-
-/**
- * A helper class for printing indented text. This can be used stand-alone or, more commonly, from Builders.
- * <p>
- * By default, a PrintWriter to System.out is used as the Writer, but it is possible
- * to change the Writer by passing a new one as a constructor argument.
- * <p>
- * Indention by default is 2 characters but can be changed by passing a
- * different value as a constructor argument.
- * <p>
- * The following is an example usage. Note that within a "with" block you need to
- * specify a parameter name so that this.println is not called instead of IndentPrinter.println:
- * <pre>
- * new IndentPrinter(new PrintWriter(out)).with { p ->
- * p.printIndent()
- * p.println('parent1')
- * p.incrementIndent()
- * p.printIndent()
- * p.println('child 1')
- * p.printIndent()
- * p.println('child 2')
- * p.decrementIndent()
- * p.printIndent()
- * p.println('parent2')
- * p.flush()
- * }
- * </pre>
- * The above example prints this to standard output:
- * <pre>
- * parent1
- * child 1
- * child 2
- * parent2
- * </pre>
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- */
-public class IndentPrinter {
-
- private int indentLevel;
- private final String indent;
- private final Writer out;
- private final boolean addNewlines;
- private boolean autoIndent;
-
- /**
- * Creates an IndentPrinter backed by a PrintWriter pointing to System.out, with an indent of two spaces.
- *
- * @see #IndentPrinter(Writer, String)
- */
- public IndentPrinter() {
- this(new PrintWriter(System.out), " ");
- }
-
- /**
- * Creates an IndentPrinter backed by the supplied Writer, with an indent of two spaces.
- *
- * @param out Writer to output to
- * @see #IndentPrinter(Writer, String)
- */
- public IndentPrinter(Writer out) {
- this(out, " ");
- }
-
- /**
- * Creates an IndentPrinter backed by the supplied Writer,
- * with a user-supplied String to be used for indenting.
- *
- * @param out Writer to output to
- * @param indent character(s) used to indent each line
- */
- public IndentPrinter(Writer out, String indent) {
- this(out, indent, true);
- }
-
- /**
- * Creates an IndentPrinter backed by the supplied Writer,
- * with a user-supplied String to be used for indenting
- * and the ability to override newline handling.
- *
- * @param out Writer to output to
- * @param indent character(s) used to indent each line
- * @param addNewlines set to false to gobble all new lines (default true)
- */
- public IndentPrinter(Writer out, String indent, boolean addNewlines) {
- this(out, indent, addNewlines, false);
- }
-
- /**
- * Create an IndentPrinter to the given PrintWriter
- * @param out Writer to output to
- * @param indent character(s) used to indent each line
- * @param addNewlines set to false to gobble all new lines (default true)
- * @param autoIndent set to true to make println() prepend the indent automatically (default false)
- */
- public IndentPrinter(Writer out, String indent, boolean addNewlines, boolean autoIndent) {
- this.addNewlines = addNewlines;
- if (out == null) {
- throw new IllegalArgumentException("Must specify a Writer");
- }
- this.out = out;
- this.indent = indent;
- this.autoIndent = autoIndent;
- }
-
- /**
- * Prints a string followed by an end of line character.
- *
- * @param text String to be written
- */
- public void println(String text) {
- try {
- if(autoIndent) printIndent();
- out.write(text);
- println();
- } catch(IOException ioe) {
- throw new GroovyRuntimeException(ioe);
- }
- }
-
- /**
- * Prints a string.
- *
- * @param text String to be written
- */
- public void print(String text) {
- try {
- out.write(text);
- } catch(IOException ioe) {
- throw new GroovyRuntimeException(ioe);
- }
- }
-
- /**
- * Prints a character.
- *
- * @param c char to be written
- */
- public void print(char c) {
- try {
- out.write(c);
- } catch(IOException ioe) {
- throw new GroovyRuntimeException(ioe);
- }
- }
-
- /**
- * Prints the current indent level.
- */
- public void printIndent() {
- for (int i = 0; i < indentLevel; i++) {
- try {
- out.write(indent);
- } catch(IOException ioe) {
- throw new GroovyRuntimeException(ioe);
- }
- }
- }
-
- /**
- * Prints an end-of-line character (if enabled via addNewLines property).
- * Defaults to outputting a single '\n' character but by using a custom
- * Writer, e.g. PlatformLineWriter, you can get platform-specific
- * end-of-line characters.
- *
- * @see #IndentPrinter(Writer, String, boolean)
- */
- public void println() {
- if (addNewlines) {
- try {
- out.write("\n");
- } catch(IOException ioe) {
- throw new GroovyRuntimeException(ioe);
- }
- }
- }
-
- public void incrementIndent() {
- ++indentLevel;
- }
-
- public void decrementIndent() {
- --indentLevel;
- }
-
- public int getIndentLevel() {
- return indentLevel;
- }
-
- public void setIndentLevel(int indentLevel) {
- this.indentLevel = indentLevel;
- }
-
- public boolean getAutoIndent(){
- return this.autoIndent;
- }
-
- public void setAutoIndent(boolean autoIndent){
- this.autoIndent = autoIndent;
- }
-
- public void flush() {
- try {
- out.flush();
- } catch(IOException ioe) {
- throw new GroovyRuntimeException(ioe);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/MapEntry.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/MapEntry.java b/src/main/groovy/util/MapEntry.java
deleted file mode 100644
index 9190fcd..0000000
--- a/src/main/groovy/util/MapEntry.java
+++ /dev/null
@@ -1,83 +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.util;
-
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-import java.util.Map;
-
-/**
- * A Map.Entry implementation.
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- */
-public class MapEntry implements Map.Entry {
-
- private Object key;
- private Object value;
-
- public MapEntry(Object key, Object value) {
- this.key = key;
- this.value = value;
- }
-
- public boolean equals(Object that) {
- if (that instanceof MapEntry) {
- return equals((MapEntry) that);
- }
- return false;
- }
-
- public boolean equals(MapEntry that) {
- return DefaultTypeTransformation.compareEqual(this.key, that.key) && DefaultTypeTransformation.compareEqual(this.value, that.value);
- }
-
- public int hashCode() {
- return hash(key) ^ hash(value);
- }
-
- public String toString() {
- return "" + key + ":" + value;
- }
-
- public Object getKey() {
- return key;
- }
-
- public void setKey(Object key) {
- this.key = key;
- }
-
- public Object getValue() {
- return value;
- }
-
- public Object setValue(Object value) {
- this.value = value;
- return value;
- }
-
- /**
- * Helper method to handle object hashes for possibly null values
- */
- protected int hash(Object object) {
- return (object == null) ? 0xbabe : object.hashCode();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/Node.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/Node.java b/src/main/groovy/util/Node.java
deleted file mode 100644
index e40b14a..0000000
--- a/src/main/groovy/util/Node.java
+++ /dev/null
@@ -1,787 +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.util;
-
-import groovy.lang.Closure;
-import groovy.lang.DelegatingMetaClass;
-import groovy.lang.GroovySystem;
-import groovy.lang.MetaClass;
-import groovy.lang.Tuple2;
-import groovy.xml.QName;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.util.ListHashMap;
-
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * Represents an arbitrary tree node which can be used for structured metadata or any arbitrary XML-like tree.
- * A node can have a name, a value and an optional Map of attributes.
- * Typically the name is a String and a value is either a String or a List of other Nodes,
- * though the types are extensible to provide a flexible structure, e.g. you could use a
- * QName as the name which includes a namespace URI and a local name. Or a JMX ObjectName etc.
- * So this class can represent metadata like <code>{foo a=1 b="abc"}</code> or nested
- * metadata like <code>{foo a=1 b="123" { bar x=12 text="hello" }}</code>
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- * @author Paul King
- */
-public class Node implements Serializable, Cloneable {
-
- static {
- // wrap the standard MetaClass with the delegate
- setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(Node.class), Node.class);
- }
-
- private static final long serialVersionUID = 4121134753270542643L;
-
- private Node parent;
-
- private final Object name;
-
- private final Map attributes;
-
- private Object value;
-
- /**
- * Creates a new Node with the same name, no parent, shallow cloned attributes
- * and if the value is a NodeList, a (deep) clone of those nodes.
- *
- * @return the clone
- */
- @Override
- public Object clone() {
- Object newValue = value;
- if (value != null && value instanceof NodeList) {
- NodeList nodes = (NodeList) value;
- newValue = nodes.clone();
- }
- return new Node(null, name, new HashMap(attributes), newValue);
- }
-
- /**
- * Creates a new Node named <code>name</code> and if a parent is supplied, adds
- * the newly created node as a child of the parent.
- *
- * @param parent the parent node or null if no parent
- * @param name the name of the node
- */
- public Node(Node parent, Object name) {
- this(parent, name, new NodeList());
- }
-
- /**
- * Creates a new Node named <code>name</code> with value <code>value</code> and
- * if a parent is supplied, adds the newly created node as a child of the parent.
- *
- * @param parent the parent node or null if no parent
- * @param name the name of the node
- * @param value the Node value, e.g. some text but in general any Object
- */
- public Node(Node parent, Object name, Object value) {
- this(parent, name, new HashMap(), value);
- }
-
- /**
- * Creates a new Node named <code>name</code> with
- * attributes specified in the <code>attributes</code> Map. If a parent is supplied,
- * the newly created node is added as a child of the parent.
- *
- * @param parent the parent node or null if no parent
- * @param name the name of the node
- * @param attributes a Map of name-value pairs
- */
- public Node(Node parent, Object name, Map attributes) {
- this(parent, name, attributes, new NodeList());
- }
-
- /**
- * Creates a new Node named <code>name</code> with value <code>value</code> and
- * with attributes specified in the <code>attributes</code> Map. If a parent is supplied,
- * the newly created node is added as a child of the parent.
- *
- * @param parent the parent node or null if no parent
- * @param name the name of the node
- * @param attributes a Map of name-value pairs
- * @param value the Node value, e.g. some text but in general any Object
- */
- public Node(Node parent, Object name, Map attributes, Object value) {
- this.parent = parent;
- this.name = name;
- this.attributes = attributes;
- this.value = value;
-
- if (parent != null) {
- getParentList(parent).add(this);
- }
- }
-
- private static List getParentList(Node parent) {
- Object parentValue = parent.value();
- List parentList;
- if (parentValue instanceof List) {
- parentList = (List) parentValue;
- } else {
- parentList = new NodeList();
- parentList.add(parentValue);
- parent.setValue(parentList);
- }
- return parentList;
- }
-
- /**
- * Appends a child to the current node.
- *
- * @param child the child to append
- * @return <code>true</code>
- */
- public boolean append(Node child) {
- child.setParent(this);
- return getParentList(this).add(child);
- }
-
- /**
- * Removes a child of the current node.
- *
- * @param child the child to remove
- * @return <code>true</code> if the param was a child of the current node
- */
- public boolean remove(Node child) {
- child.setParent(null);
- return getParentList(this).remove(child);
- }
-
- /**
- * Creates a new node as a child of the current node.
- *
- * @param name the name of the new node
- * @param attributes the attributes of the new node
- * @return the newly created <code>Node</code>
- */
- public Node appendNode(Object name, Map attributes) {
- return new Node(this, name, attributes);
- }
-
- /**
- * Creates a new node as a child of the current node.
- *
- * @param name the name of the new node
- * @return the newly created <code>Node</code>
- */
- public Node appendNode(Object name) {
- return new Node(this, name);
- }
-
- /**
- * Creates a new node as a child of the current node.
- *
- * @param name the name of the new node
- * @param value the value of the new node
- * @return the newly created <code>Node</code>
- */
- public Node appendNode(Object name, Object value) {
- return new Node(this, name, value);
- }
-
- /**
- * Creates a new node as a child of the current node.
- *
- * @param name the name of the new node
- * @param attributes the attributes of the new node
- * @param value the value of the new node
- * @return the newly created <code>Node</code>
- */
- public Node appendNode(Object name, Map attributes, Object value) {
- return new Node(this, name, attributes, value);
- }
-
- /**
- * Replaces the current node with nodes defined using builder-style notation via a Closure.
- *
- * @param c A Closure defining the new nodes using builder-style notation.
- * @return the original now replaced node
- */
- public Node replaceNode(Closure c) {
- if (parent() == null) {
- throw new UnsupportedOperationException("Replacing the root node is not supported");
- }
- appendNodes(c);
- getParentList(parent()).remove(this);
- this.setParent(null);
- return this;
- }
-
- /**
- * Replaces the current node with the supplied node.
- *
- * @param n the new Node
- * @return the original now replaced node
- */
- public Node replaceNode(Node n) {
- if (parent() == null) {
- throw new UnsupportedOperationException("Replacing the root node is not supported");
- }
- List tail = getTail();
- parent().appendNode(n.name(), n.attributes(), n.value());
- parent().children().addAll(tail);
- getParentList(parent()).remove(this);
- this.setParent(null);
- return this;
- }
-
- private List getTail() {
- List list = parent().children();
- int afterIndex = list.indexOf(this);
- List tail = new ArrayList(list.subList(afterIndex + 1, list.size()));
- list.subList(afterIndex + 1, list.size()).clear();
- return tail;
- }
-
- /**
- * Adds sibling nodes (defined using builder-style notation via a Closure) after the current node.
- *
- * @param c A Closure defining the new sibling nodes to add using builder-style notation.
- */
- public void plus(Closure c) {
- if (parent() == null) {
- throw new UnsupportedOperationException("Adding sibling nodes to the root node is not supported");
- }
- appendNodes(c);
- }
-
- private void appendNodes(Closure c) {
- List tail = getTail();
- for (Node child : buildChildrenFromClosure(c)) {
- parent().appendNode(child.name(), child.attributes(), child.value());
- }
- parent().children().addAll(tail);
- }
-
- private static List<Node> buildChildrenFromClosure(Closure c) {
- NodeBuilder b = new NodeBuilder();
- Node newNode = (Node) b.invokeMethod("dummyNode", c);
- return newNode.children();
- }
-
- /**
- * Extension point for subclasses to override the metaclass. The default
- * one supports the property and @ attribute notations.
- *
- * @param metaClass the original metaclass
- * @param nodeClass the class whose metaclass we wish to override (this class or a subclass)
- */
- protected static void setMetaClass(final MetaClass metaClass, Class nodeClass) {
- // TODO Is protected static a bit of a smell?
- // TODO perhaps set nodeClass to be Class<? extends Node>
- final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
- @Override
- public Object getAttribute(final Object object, final String attribute) {
- Node n = (Node) object;
- return n.get("@" + attribute);
- }
-
- @Override
- public void setAttribute(final Object object, final String attribute, final Object newValue) {
- Node n = (Node) object;
- n.attributes().put(attribute, newValue);
- }
-
- @Override
- public Object getProperty(Object object, String property) {
- if (object instanceof Node) {
- Node n = (Node) object;
- return n.get(property);
- }
- return super.getProperty(object, property);
- }
-
- @Override
- public void setProperty(Object object, String property, Object newValue) {
- if (property.startsWith("@")) {
- setAttribute(object, property.substring(1), newValue);
- return;
- }
- delegate.setProperty(object, property, newValue);
- }
-
- };
- GroovySystem.getMetaClassRegistry().setMetaClass(nodeClass, newMetaClass);
- }
-
- /**
- * Returns the textual representation of the current node and all its child nodes.
- *
- * @return the text value of the node including child text
- */
- public String text() {
- if (value instanceof String) {
- return (String) value;
- }
- if (value instanceof NodeList) {
- return ((NodeList) value).text();
- }
- if (value instanceof Collection) {
- Collection coll = (Collection) value;
- String previousText = null;
- StringBuilder sb = null;
- for (Object child : coll) {
- String childText = null;
- if (child instanceof String) {
- childText = (String) child;
- } else if (child instanceof Node) {
- childText = ((Node) child).text();
- }
- if (childText != null) {
- if (previousText == null) {
- previousText = childText;
- } else {
- if (sb == null) {
- sb = new StringBuilder();
- sb.append(previousText);
- }
- sb.append(childText);
- }
- }
- }
- if (sb != null) {
- return sb.toString();
- } else {
- if (previousText != null) {
- return previousText;
- }
- return "";
- }
- }
- return "" + value;
- }
-
- /**
- * Returns an <code>Iterator</code> of the children of the node.
- *
- * @return the iterator of the nodes children
- */
- public Iterator iterator() {
- return children().iterator();
- }
-
- /**
- * Returns a <code>List</code> of the nodes children.
- *
- * @return the nodes children
- */
- public List children() {
- if (value == null) {
- return new NodeList();
- }
- if (value instanceof List) {
- return (List) value;
- }
- // we're probably just a String
- List result = new NodeList();
- result.add(value);
- return result;
- }
-
- /**
- * Returns a <code>Map</code> of the attributes of the node or an empty <code>Map</code>
- * if the node does not have any attributes.
- *
- * @return the attributes of the node
- */
- public Map attributes() {
- return attributes;
- }
-
- /**
- * Provides lookup of attributes by key.
- *
- * @param key the key of interest
- * @return the attribute matching the key or <code>null</code> if no match exists
- */
- public Object attribute(Object key) {
- return (attributes != null) ? attributes.get(key) : null;
- }
-
- /**
- * Returns an <code>Object</code> representing the name of the node.
- *
- * @return the name or <code>null</code> if name is empty
- */
- public Object name() {
- return name;
- }
-
- /**
- * Returns an <code>Object</code> representing the value of the node.
- *
- * @return the value or <code>null</code> if value is empty
- */
- public Object value() {
- return value;
- }
-
- /**
- * Adds or replaces the value of the node.
- *
- * @param value the new value of the node
- */
- public void setValue(Object value) {
- this.value = value;
- }
-
- /**
- * Returns the parent of the node.
- *
- * @return the parent or <code>null</code> for the root node
- */
- public Node parent() {
- return parent;
- }
-
- /**
- * Adds or replaces the parent of the node.
- *
- * @param parent the new parent of the node
- */
- protected void setParent(Node parent) {
- this.parent = parent;
- }
-
- /**
- * Provides lookup of elements by non-namespaced name
- *
- * @param key the name (or shortcut key) of the node(s) of interest
- * @return the nodes which match key
- */
- public Object get(String key) {
- if (key != null && key.charAt(0) == '@') {
- String attributeName = key.substring(1);
- return attributes().get(attributeName);
- }
- if ("..".equals(key)) {
- return parent();
- }
- if ("*".equals(key)) {
- return children();
- }
- if ("**".equals(key)) {
- return depthFirst();
- }
- return getByName(key);
- }
-
- /**
- * Provides lookup of elements by QName.
- *
- * @param name the QName of interest
- * @return the nodes matching name
- */
- public NodeList getAt(QName name) {
- NodeList answer = new NodeList();
- for (Object child : children()) {
- if (child instanceof Node) {
- Node childNode = (Node) child;
- Object childNodeName = childNode.name();
- if (name.matches(childNodeName)) {
- answer.add(childNode);
- }
- }
- }
- return answer;
- }
-
- /**
- * Provides lookup of elements by name.
- *
- * @param name the name of interest
- * @return the nodes matching name
- */
- private NodeList getByName(String name) {
- NodeList answer = new NodeList();
- for (Object child : children()) {
- if (child instanceof Node) {
- Node childNode = (Node) child;
- Object childNodeName = childNode.name();
- if (childNodeName instanceof QName) {
- QName qn = (QName) childNodeName;
- if (qn.matches(name)) {
- answer.add(childNode);
- }
- } else if (name.equals(childNodeName)) {
- answer.add(childNode);
- }
- }
- }
- return answer;
- }
-
- /**
- * Provides a collection of all the nodes in the tree
- * using a depth-first preorder traversal.
- *
- * @return the list of (depth-first) ordered nodes
- */
- public List depthFirst() {
- return depthFirst(true);
- }
-
- /**
- * Provides a collection of all the nodes in the tree
- * using a depth-first traversal.
- *
- * @param preorder if false, a postorder depth-first traversal will be performed
- * @return the list of (depth-first) ordered nodes
- * @since 2.5.0
- */
- public List depthFirst(boolean preorder) {
- List answer = new NodeList();
- if (preorder) answer.add(this);
- answer.addAll(depthFirstRest(preorder));
- if (!preorder) answer.add(this);
- return answer;
- }
-
- private List depthFirstRest(boolean preorder) {
- List answer = new NodeList();
- for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
- Object child = iter.next();
- if (child instanceof Node) {
- Node childNode = (Node) child;
- List children = childNode.depthFirstRest(preorder);
- if (preorder) answer.add(childNode);
- if (children.size() > 1 || (children.size() == 1 && !(children.get(0) instanceof String))) answer.addAll(children);
- if (!preorder) answer.add(childNode);
- } else if (child instanceof String) {
- answer.add(child);
- }
- }
- return answer;
- }
-
- /**
- * Provides a collection of all the nodes in the tree
- * using a depth-first preorder traversal.
- *
- * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
- * closure will be passed the node, for a two param closure the second parameter will be the level).
- * @since 2.5.0
- */
- public void depthFirst(Closure c) {
- Map<String, Object> options = new ListHashMap<String, Object>();
- options.put("preorder", true);
- depthFirst(options, c);
- }
-
- /**
- * Provides a collection of all the nodes in the tree
- * using a depth-first traversal.
- * A boolean 'preorder' options is supported.
- *
- * @param options map containing options
- * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
- * closure will be passed the node, for a two param closure the second parameter will be the level).
- * @since 2.5.0
- */
- public void depthFirst(Map<String, Object> options, Closure c) {
- boolean preorder = Boolean.valueOf(options.get("preorder").toString());
- if (preorder) callClosureForNode(c, this, 1);
- depthFirstRest(preorder, 2, c);
- if (!preorder) callClosureForNode(c, this, 1);
- }
-
- private static <T> T callClosureForNode(Closure<T> closure, Object node, int level) {
- if (closure.getMaximumNumberOfParameters() == 2) {
- return closure.call(new Object[]{node, level});
- }
- return closure.call(node);
- }
-
- private void depthFirstRest(boolean preorder, int level, Closure c) {
- for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
- Object child = iter.next();
- if (child instanceof Node) {
- Node childNode = (Node) child;
- if (preorder) callClosureForNode(c, childNode, level);
- childNode.depthFirstRest(preorder, level + 1, c);
- if (!preorder) callClosureForNode(c, childNode, level);
- }
- }
- }
-
- /**
- * Provides a collection of all the nodes in the tree
- * using a breadth-first preorder traversal.
- *
- * @return the list of (breadth-first) ordered nodes
- */
- public List breadthFirst() {
- return breadthFirst(true);
- }
-
- /**
- * Provides a collection of all the nodes in the tree
- * using a breadth-first traversal.
- *
- * @param preorder if false, a postorder breadth-first traversal will be performed
- * @return the list of (breadth-first) ordered nodes
- * @since 2.5.0
- */
- public List breadthFirst(boolean preorder) {
- List answer = new NodeList();
- if (preorder) answer.add(this);
- answer.addAll(breadthFirstRest(preorder));
- if (!preorder) answer.add(this);
- return answer;
- }
-
- private List breadthFirstRest(boolean preorder) {
- List answer = new NodeList();
- Stack stack = new Stack();
- List nextLevelChildren = preorder ? getDirectChildren() : DefaultGroovyMethods.reverse(getDirectChildren());
- while (!nextLevelChildren.isEmpty()) {
- List working = new NodeList(nextLevelChildren);
- nextLevelChildren = new NodeList();
- for (Object child : working) {
- if (preorder) {
- answer.add(child);
- } else {
- stack.push(child);
- }
- if (child instanceof Node) {
- Node childNode = (Node) child;
- List children = childNode.getDirectChildren();
- if (children.size() > 1 || (children.size() == 1 && !(children.get(0) instanceof String))) nextLevelChildren.addAll(preorder ? children : DefaultGroovyMethods.reverse(children));
- }
- }
- }
- while (!stack.isEmpty()) {
- answer.add(stack.pop());
- }
- return answer;
- }
-
- /**
- * Calls the provided closure for all the nodes in the tree
- * using a breadth-first preorder traversal.
- *
- * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
- * closure will be passed the node, for a two param closure the second parameter will be the level).
- * @since 2.5.0
- */
- public void breadthFirst(Closure c) {
- Map<String, Object> options = new ListHashMap<String, Object>();
- options.put("preorder", true);
- breadthFirst(options, c);
- }
-
- /**
- * Calls the provided closure for all the nodes in the tree
- * using a breadth-first traversal.
- * A boolean 'preorder' options is supported.
- *
- * @param options map containing options
- * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
- * closure will be passed the node, for a two param closure the second parameter will be the level).
- * @since 2.5.0
- */
- public void breadthFirst(Map<String, Object> options, Closure c) {
- boolean preorder = Boolean.valueOf(options.get("preorder").toString());
- if (preorder) callClosureForNode(c, this, 1);
- breadthFirstRest(preorder, 2, c);
- if (!preorder) callClosureForNode(c, this, 1);
- }
-
- private void breadthFirstRest(boolean preorder, int level, Closure c) {
- Stack<Tuple2<Object, Integer>> stack = new Stack<Tuple2<Object, Integer>>();
- List nextLevelChildren = preorder ? getDirectChildren() : DefaultGroovyMethods.reverse(getDirectChildren());
- while (!nextLevelChildren.isEmpty()) {
- List working = new NodeList(nextLevelChildren);
- nextLevelChildren = new NodeList();
- for (Object child : working) {
- if (preorder) {
- callClosureForNode(c, child, level);
- } else {
- stack.push(new Tuple2<Object, Integer>(child, level));
- }
- if (child instanceof Node) {
- Node childNode = (Node) child;
- List children = childNode.getDirectChildren();
- if (children.size() > 1 || (children.size() == 1 && !(children.get(0) instanceof String))) nextLevelChildren.addAll(preorder ? children : DefaultGroovyMethods.reverse(children));
- }
- }
- level++;
- }
- while (!stack.isEmpty()) {
- Tuple2<Object, Integer> next = stack.pop();
- callClosureForNode(c, next.getFirst(), next.getSecond());
- }
- }
-
- /**
- * Returns the list of any direct String nodes of this node.
- *
- * @return the list of String values from this node
- * @since 2.3.0
- */
- public List<String> localText() {
- List<String> answer = new ArrayList<String>();
- for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
- Object child = iter.next();
- if (!(child instanceof Node)) {
- answer.add(child.toString());
- }
- }
- return answer;
- }
-
- private List getDirectChildren() {
- List answer = new NodeList();
- for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
- Object child = iter.next();
- if (child instanceof Node) {
- Node childNode = (Node) child;
- answer.add(childNode);
- } else if (child instanceof String) {
- answer.add(child);
- }
- }
- return answer;
- }
-
- public String toString() {
- return name + "[attributes=" + attributes + "; value=" + value + "]";
- }
-
- /**
- * Writes the node to the specified <code>PrintWriter</code>.
- *
- * @param out the writer receiving the output
- */
- public void print(PrintWriter out) {
- new NodePrinter(out).print(this);
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/NodeBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/NodeBuilder.java b/src/main/groovy/util/NodeBuilder.java
deleted file mode 100644
index babe5c3..0000000
--- a/src/main/groovy/util/NodeBuilder.java
+++ /dev/null
@@ -1,57 +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.util;
-
-import java.util.Map;
-
-/**
- * A helper class for creating nested trees of Node objects for
- * handling arbitrary data
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- */
-public class NodeBuilder extends BuilderSupport {
-
- public static NodeBuilder newInstance() {
- return new NodeBuilder();
- }
-
- protected void setParent(Object parent, Object child) {
- }
-
- protected Object createNode(Object name) {
- return new Node(getCurrentNode(), name);
- }
-
- protected Object createNode(Object name, Object value) {
- return new Node(getCurrentNode(), name, value);
- }
-
- protected Object createNode(Object name, Map attributes) {
- return new Node(getCurrentNode(), name, attributes);
- }
-
- protected Object createNode(Object name, Map attributes, Object value) {
- return new Node(getCurrentNode(), name, attributes, value);
- }
-
- protected Node getCurrentNode() {
- return (Node) getCurrent();
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/NodeList.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/NodeList.java b/src/main/groovy/util/NodeList.java
deleted file mode 100644
index e54009c..0000000
--- a/src/main/groovy/util/NodeList.java
+++ /dev/null
@@ -1,202 +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.util;
-
-import groovy.lang.Closure;
-import groovy.lang.DelegatingMetaClass;
-import groovy.lang.GroovyRuntimeException;
-import groovy.lang.GroovySystem;
-import groovy.lang.MetaClass;
-import groovy.xml.QName;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A List implementation which is returned by queries on a {@link Node}
- * which provides some XPath like helper methods for GPath.
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- * @author Paul King
- */
-public class NodeList extends ArrayList {
- static {
- // wrap the standard MetaClass with the delegate
- setMetaClass(NodeList.class, GroovySystem.getMetaClassRegistry().getMetaClass(NodeList.class));
- }
-
- public NodeList() {
- }
-
- public NodeList(Collection collection) {
- super(collection);
- }
-
- public NodeList(int size) {
- super(size);
- }
-
- /**
- * Creates a new NodeList containing the same elements as the
- * original (but cloned in the case of Nodes).
- *
- * @return the clone
- */
- @Override
- public Object clone() {
- NodeList result = new NodeList(size());
- for (int i = 0; i < size(); i++) {
- Object next = get(i);
- if (next instanceof Node) {
- Node n = (Node) next;
- result.add(n.clone());
- } else {
- result.add(next);
- }
- }
- return result;
- }
-
- protected static void setMetaClass(final Class nodelistClass, final MetaClass metaClass) {
- final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
- @Override
- public Object getAttribute(final Object object, final String attribute) {
- NodeList nl = (NodeList) object;
- Iterator it = nl.iterator();
- List result = new ArrayList();
- while (it.hasNext()) {
- Node node = (Node) it.next();
- result.add(node.attributes().get(attribute));
- }
- return result;
- }
-
- @Override
- public void setAttribute(final Object object, final String attribute, final Object newValue) {
- for (Object o : (NodeList) object) {
- Node node = (Node) o;
- node.attributes().put(attribute, newValue);
- }
- }
-
- @Override
- public Object getProperty(Object object, String property) {
- if (object instanceof NodeList) {
- NodeList nl = (NodeList) object;
- return nl.getAt(property);
- }
- return super.getProperty(object, property);
- }
- };
- GroovySystem.getMetaClassRegistry().setMetaClass(nodelistClass, newMetaClass);
- }
-
- /**
- * Provides lookup of elements by non-namespaced name.
- *
- * @param name the name or shortcut key for nodes of interest
- * @return the nodes of interest which match name
- */
- public NodeList getAt(String name) {
- NodeList answer = new NodeList();
- for (Object child : this) {
- if (child instanceof Node) {
- Node childNode = (Node) child;
- Object temp = childNode.get(name);
- if (temp instanceof Collection) {
- answer.addAll((Collection) temp);
- } else {
- answer.add(temp);
- }
- }
- }
- return answer;
- }
-
- /**
- * Provides lookup of elements by QName.
- *
- * @param name the name or shortcut key for nodes of interest
- * @return the nodes of interest which match name
- */
- public NodeList getAt(QName name) {
- NodeList answer = new NodeList();
- for (Object child : this) {
- if (child instanceof Node) {
- Node childNode = (Node) child;
- NodeList temp = childNode.getAt(name);
- answer.addAll(temp);
- }
- }
- return answer;
- }
-
- /**
- * Returns the text value of all of the elements in the collection.
- *
- * @return the text value of all the elements in the collection or null
- */
- public String text() {
- String previousText = null;
- StringBuilder buffer = null;
- for (Object child : this) {
- String text = null;
- if (child instanceof String) {
- text = (String) child;
- } else if (child instanceof Node) {
- text = ((Node) child).text();
- }
- if (text != null) {
- if (previousText == null) {
- previousText = text;
- } else {
- if (buffer == null) {
- buffer = new StringBuilder();
- buffer.append(previousText);
- }
- buffer.append(text);
- }
- }
- }
- if (buffer != null) {
- return buffer.toString();
- }
- if (previousText != null) {
- return previousText;
- }
- return "";
- }
-
- public Node replaceNode(Closure c) {
- if (size() <= 0 || size() > 1) {
- throw new GroovyRuntimeException(
- "replaceNode() can only be used to replace a single node, but was applied to " + size() + " nodes");
- }
- return ((Node)get(0)).replaceNode(c);
- }
-
- public void plus(Closure c) {
- for (Object o : this) {
- ((Node) o).plus(c);
- }
- }
-
-}