You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 04:29:10 UTC
[02/47] groovy git commit: Move source files to proper packages
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/util/NodePrinter.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/NodePrinter.java b/src/main/groovy/util/NodePrinter.java
deleted file mode 100644
index ca93bc7..0000000
--- a/src/main/groovy/util/NodePrinter.java
+++ /dev/null
@@ -1,130 +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.InvokerHelper;
-
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A helper class for creating nested trees of data
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- * @author Christian Stein
- */
-public class NodePrinter {
-
- protected final IndentPrinter out;
-
- public NodePrinter() {
- this(new IndentPrinter(new PrintWriter(new OutputStreamWriter(System.out))));
- }
-
- public NodePrinter(PrintWriter out) {
- this(new IndentPrinter(out));
- }
-
- public NodePrinter(IndentPrinter out) {
- if (out == null) {
- throw new NullPointerException("IndentPrinter 'out' must not be null!");
- }
- this.out = out;
- }
-
- public void print(Node node) {
- out.printIndent();
- printName(node);
- Map attributes = node.attributes();
- boolean hasAttributes = attributes != null && !attributes.isEmpty();
- if (hasAttributes) {
- printAttributes(attributes);
- }
- Object value = node.value();
- if (value instanceof List) {
- if (!hasAttributes) {
- out.print("()");
- }
- printList((List) value);
- } else {
- if (value instanceof String) {
- out.print("('");
- out.print((String) value);
- out.println("')");
- } else {
- out.println("()");
- }
- }
- out.flush();
- }
-
- protected void printName(Node node) {
- Object name = node.name();
- if (name != null) {
- out.print(name.toString());
- } else {
- out.print("null");
- }
- }
-
- protected void printList(List list) {
- if (list.isEmpty()) {
- out.println("");
- } else {
- out.println(" {");
- out.incrementIndent();
- for (Object value : list) {
- if (value instanceof Node) {
- print((Node) value);
- } else {
- out.printIndent();
- out.println(InvokerHelper.toString(value));
- }
- }
- out.decrementIndent();
- out.printIndent();
- out.println("}");
- }
- }
-
-
- protected void printAttributes(Map attributes) {
- out.print("(");
- boolean first = true;
- for (Object o : attributes.entrySet()) {
- Map.Entry entry = (Map.Entry) o;
- if (first) {
- first = false;
- } else {
- out.print(", ");
- }
- out.print(entry.getKey().toString());
- out.print(":");
- if (entry.getValue() instanceof String) {
- out.print("'" + entry.getValue() + "'");
- } else {
- out.print(InvokerHelper.toString(entry.getValue()));
- }
- }
- out.print(")");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/util/ObjectGraphBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/ObjectGraphBuilder.java b/src/main/groovy/util/ObjectGraphBuilder.java
deleted file mode 100644
index 7ba0089..0000000
--- a/src/main/groovy/util/ObjectGraphBuilder.java
+++ /dev/null
@@ -1,857 +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.GString;
-import groovy.lang.MetaProperty;
-import groovy.lang.MissingPropertyException;
-import org.codehaus.groovy.runtime.InvokerHelper;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * A builder for creating object graphs.<br>
- * Each node defines the class to be created and the property on its parent (if
- * any) at the same time.
- *
- * @author Scott Vlaminck (http://refactr.com)
- * @author <a href="mailto:aalmiray@users.sourceforge.com">Andres Almiray</a>
- */
-public class ObjectGraphBuilder extends FactoryBuilderSupport {
- public static final String NODE_CLASS = "_NODE_CLASS_";
- public static final String NODE_NAME = "_NODE_NAME_";
- public static final String OBJECT_ID = "_OBJECT_ID_";
- public static final String LAZY_REF = "_LAZY_REF_";
-
- public static final String CLASSNAME_RESOLVER_KEY = "name";
- public static final String CLASSNAME_RESOLVER_REFLECTION = "reflection";
- public static final String CLASSNAME_RESOLVER_REFLECTION_ROOT = "root";
-
- // Regular expression pattern used to identify words ending in 'y' preceded by a consonant
- private static final Pattern PLURAL_IES_PATTERN = Pattern.compile(".*[^aeiouy]y", Pattern.CASE_INSENSITIVE);
-
- private ChildPropertySetter childPropertySetter;
- private ClassNameResolver classNameResolver;
- private IdentifierResolver identifierResolver;
- private NewInstanceResolver newInstanceResolver;
- private final ObjectFactory objectFactory = new ObjectFactory();
- private final ObjectBeanFactory objectBeanFactory = new ObjectBeanFactory();
- private final ObjectRefFactory objectRefFactory = new ObjectRefFactory();
- private ReferenceResolver referenceResolver;
- private RelationNameResolver relationNameResolver;
- private final Map<String, Class> resolvedClasses = new HashMap<String, Class>();
- private ClassLoader classLoader;
- private boolean lazyReferencesAllowed = true;
- private final List<NodeReference> lazyReferences = new ArrayList<NodeReference>();
- private String beanFactoryName = "bean";
-
- public ObjectGraphBuilder() {
- classNameResolver = new DefaultClassNameResolver();
- newInstanceResolver = new DefaultNewInstanceResolver();
- relationNameResolver = new DefaultRelationNameResolver();
- childPropertySetter = new DefaultChildPropertySetter();
- identifierResolver = new DefaultIdentifierResolver();
- referenceResolver = new DefaultReferenceResolver();
-
- addPostNodeCompletionDelegate(new Closure(this, this) {
- public void doCall(ObjectGraphBuilder builder, Object parent, Object node) {
- if (parent == null) {
- builder.resolveLazyReferences();
- builder.dispose();
- }
- }
- });
- }
-
- /**
- * Returns the current name of the 'bean' node.
- */
- public String getBeanFactoryName() {
- return beanFactoryName;
- }
-
- /**
- * Returns the current ChildPropertySetter.
- */
- public ChildPropertySetter getChildPropertySetter() {
- return childPropertySetter;
- }
-
- /**
- * Returns the classLoader used to load a node's class.
- */
- public ClassLoader getClassLoader() {
- return classLoader;
- }
-
- /**
- * Returns the current ClassNameResolver.
- */
- public ClassNameResolver getClassNameResolver() {
- return classNameResolver;
- }
-
- /**
- * Returns the current NewInstanceResolver.
- */
- public NewInstanceResolver getNewInstanceResolver() {
- return newInstanceResolver;
- }
-
- /**
- * Returns the current RelationNameResolver.
- */
- public RelationNameResolver getRelationNameResolver() {
- return relationNameResolver;
- }
-
- /**
- * Returns true if references can be resolved lazily
- */
- public boolean isLazyReferencesAllowed() {
- return lazyReferencesAllowed;
- }
-
- /**
- * Sets the name for the 'bean' node.
- */
- public void setBeanFactoryName(String beanFactoryName) {
- this.beanFactoryName = beanFactoryName;
- }
-
- /**
- * Sets the current ChildPropertySetter.<br>
- * It will assign DefaultChildPropertySetter if null.<br>
- * It accepts a ChildPropertySetter instance or a Closure.
- */
- public void setChildPropertySetter(final Object childPropertySetter) {
- if (childPropertySetter instanceof ChildPropertySetter) {
- this.childPropertySetter = (ChildPropertySetter) childPropertySetter;
- } else if (childPropertySetter instanceof Closure) {
- final ObjectGraphBuilder self = this;
- this.childPropertySetter = new ChildPropertySetter() {
- public void setChild(Object parent, Object child, String parentName,
- String propertyName) {
- Closure cls = (Closure) childPropertySetter;
- cls.setDelegate(self);
- cls.call(new Object[]{parent, child, parentName, propertyName});
- }
- };
- } else {
- this.childPropertySetter = new DefaultChildPropertySetter();
- }
- }
-
- /**
- * Sets the classLoader used to load a node's class.
- */
- public void setClassLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- /**
- * Sets the current ClassNameResolver.<br>
- * It will assign DefaultClassNameResolver if null.<br>
- * It accepts a ClassNameResolver instance, a String, a Closure or a Map.
- */
- public void setClassNameResolver(final Object classNameResolver) {
- if (classNameResolver instanceof ClassNameResolver) {
- this.classNameResolver = (ClassNameResolver) classNameResolver;
- } else if (classNameResolver instanceof String) {
- this.classNameResolver = new ClassNameResolver() {
- public String resolveClassname(String classname) {
- return makeClassName((String) classNameResolver, classname);
- }
- };
- } else if (classNameResolver instanceof Closure) {
- final ObjectGraphBuilder self = this;
- this.classNameResolver = new ClassNameResolver() {
- public String resolveClassname(String classname) {
- Closure cls = (Closure) classNameResolver;
- cls.setDelegate(self);
- return (String) cls.call(new Object[]{classname});
- }
- };
- } else if (classNameResolver instanceof Map) {
- Map classNameResolverOptions = (Map) classNameResolver;
-
- String resolverName = (String) classNameResolverOptions.get(CLASSNAME_RESOLVER_KEY);
-
- if (resolverName == null) {
- throw new RuntimeException("key '" + CLASSNAME_RESOLVER_KEY + "' not defined");
- }
-
- if (CLASSNAME_RESOLVER_REFLECTION.equals(resolverName)) {
- String root = (String) classNameResolverOptions.get(CLASSNAME_RESOLVER_REFLECTION_ROOT);
-
- if (root == null) {
- throw new RuntimeException("key '" + CLASSNAME_RESOLVER_REFLECTION_ROOT + "' not defined");
- }
-
- this.classNameResolver = new ReflectionClassNameResolver(root);
- } else {
- throw new RuntimeException("unknown class name resolver " + resolverName);
- }
- } else {
- this.classNameResolver = new DefaultClassNameResolver();
- }
- }
-
- /**
- * Sets the current IdentifierResolver.<br>
- * It will assign DefaultIdentifierResolver if null.<br>
- * It accepts a IdentifierResolver instance, a String or a Closure.
- */
- public void setIdentifierResolver(final Object identifierResolver) {
- if (identifierResolver instanceof IdentifierResolver) {
- this.identifierResolver = (IdentifierResolver) identifierResolver;
- } else if (identifierResolver instanceof String) {
- this.identifierResolver = new IdentifierResolver() {
- public String getIdentifierFor(String nodeName) {
- return (String) identifierResolver;
- }
- };
- } else if (identifierResolver instanceof Closure) {
- final ObjectGraphBuilder self = this;
- this.identifierResolver = new IdentifierResolver() {
- public String getIdentifierFor(String nodeName) {
- Closure cls = (Closure) identifierResolver;
- cls.setDelegate(self);
- return (String) cls.call(new Object[]{nodeName});
- }
- };
- } else {
- this.identifierResolver = new DefaultIdentifierResolver();
- }
- }
-
- /**
- * Sets whether references can be resolved lazily or not.
- */
- public void setLazyReferencesAllowed(boolean lazyReferencesAllowed) {
- this.lazyReferencesAllowed = lazyReferencesAllowed;
- }
-
- /**
- * Sets the current NewInstanceResolver.<br>
- * It will assign DefaultNewInstanceResolver if null.<br>
- * It accepts a NewInstanceResolver instance or a Closure.
- */
- public void setNewInstanceResolver(final Object newInstanceResolver) {
- if (newInstanceResolver instanceof NewInstanceResolver) {
- this.newInstanceResolver = (NewInstanceResolver) newInstanceResolver;
- } else if (newInstanceResolver instanceof Closure) {
- final ObjectGraphBuilder self = this;
- this.newInstanceResolver = new NewInstanceResolver() {
- public Object newInstance(Class klass, Map attributes)
- throws InstantiationException, IllegalAccessException {
- Closure cls = (Closure) newInstanceResolver;
- cls.setDelegate(self);
- return cls.call(new Object[]{klass, attributes});
- }
- };
- } else {
- this.newInstanceResolver = new DefaultNewInstanceResolver();
- }
- }
-
- /**
- * Sets the current ReferenceResolver.<br>
- * It will assign DefaultReferenceResolver if null.<br>
- * It accepts a ReferenceResolver instance, a String or a Closure.
- */
- public void setReferenceResolver(final Object referenceResolver) {
- if (referenceResolver instanceof ReferenceResolver) {
- this.referenceResolver = (ReferenceResolver) referenceResolver;
- } else if (referenceResolver instanceof String) {
- this.referenceResolver = new ReferenceResolver() {
- public String getReferenceFor(String nodeName) {
- return (String) referenceResolver;
- }
- };
- } else if (referenceResolver instanceof Closure) {
- final ObjectGraphBuilder self = this;
- this.referenceResolver = new ReferenceResolver() {
- public String getReferenceFor(String nodeName) {
- Closure cls = (Closure) referenceResolver;
- cls.setDelegate(self);
- return (String) cls.call(new Object[]{nodeName});
- }
- };
- } else {
- this.referenceResolver = new DefaultReferenceResolver();
- }
- }
-
- /**
- * Sets the current RelationNameResolver.<br>
- * It will assign DefaultRelationNameResolver if null.
- */
- public void setRelationNameResolver(RelationNameResolver relationNameResolver) {
- this.relationNameResolver = relationNameResolver != null ? relationNameResolver
- : new DefaultRelationNameResolver();
- }
-
- protected void postInstantiate(Object name, Map attributes, Object node) {
- super.postInstantiate(name, attributes, node);
- Map context = getContext();
- String objectId = (String) context.get(OBJECT_ID);
- if (objectId != null && node != null) {
- setVariable(objectId, node);
- }
- }
-
- protected void preInstantiate(Object name, Map attributes, Object value) {
- super.preInstantiate(name, attributes, value);
- Map context = getContext();
- context.put(OBJECT_ID,
- attributes.remove(identifierResolver.getIdentifierFor((String) name)));
- }
-
- protected Factory resolveFactory(Object name, Map attributes, Object value) {
- // let custom factories be resolved first
- Factory factory = super.resolveFactory(name, attributes, value);
- if (factory != null) {
- return factory;
- }
- if (attributes.get(referenceResolver.getReferenceFor((String) name)) != null) {
- return objectRefFactory;
- }
- if (beanFactoryName != null && beanFactoryName.equals((String) name)) {
- return objectBeanFactory;
- }
- return objectFactory;
- }
-
- /**
- * Strategy for setting a child node on its parent.<br>
- * Useful for handling Lists/Arrays vs normal properties.
- */
- public interface ChildPropertySetter {
- /**
- * @param parent the parent's node value
- * @param child the child's node value
- * @param parentName the name of the parent node
- * @param propertyName the resolved relation name of the child
- */
- void setChild(Object parent, Object child, String parentName, String propertyName);
- }
-
- /**
- * Strategy for resolving a classname.
- */
- public interface ClassNameResolver {
- /**
- * @param classname the node name as written on the building code
- */
- String resolveClassname(String classname);
- }
-
- /**
- * Default impl that calls parent.propertyName = child<br>
- * If parent.propertyName is a Collection it will try to add child to the
- * collection.
- */
- public static class DefaultChildPropertySetter implements ChildPropertySetter {
- public void setChild(Object parent, Object child, String parentName, String propertyName) {
- try {
- Object property = InvokerHelper.getProperty(parent, propertyName);
- if (property != null && Collection.class.isAssignableFrom(property.getClass())) {
- ((Collection) property).add(child);
- } else {
- InvokerHelper.setProperty(parent, propertyName, child);
- }
- } catch (MissingPropertyException mpe) {
- // ignore
- }
- }
- }
-
- /**
- * Default impl that capitalizes the classname.
- */
- public static class DefaultClassNameResolver implements ClassNameResolver {
- public String resolveClassname(String classname) {
- if (classname.length() == 1) {
- return classname.toUpperCase();
- }
- return classname.substring(0, 1)
- .toUpperCase() + classname.substring(1);
- }
- }
-
- /**
- * Build objects using reflection to resolve class names.
- */
- public class ReflectionClassNameResolver implements ClassNameResolver {
- private final String root;
-
- /**
- * @param root package where the graph root class is located
- */
- public ReflectionClassNameResolver(String root) {
- this.root = root;
- }
-
- public String resolveClassname(String classname) {
- Object currentNode = getContext().get(CURRENT_NODE);
-
- if (currentNode == null) {
- return makeClassName(root, classname);
- } else {
- try {
- Class klass = currentNode.getClass().getDeclaredField(classname).getType();
-
- if (Collection.class.isAssignableFrom(klass)) {
- Type type = currentNode.getClass().getDeclaredField(classname).getGenericType();
- if (type instanceof ParameterizedType) {
- ParameterizedType ptype = (ParameterizedType) type;
- Type[] actualTypeArguments = ptype.getActualTypeArguments();
- if (actualTypeArguments.length != 1) {
- throw new RuntimeException("can't determine class name for collection field " + classname + " with multiple generics");
- }
-
- Type typeArgument = actualTypeArguments[0];
- if (typeArgument instanceof Class) {
- klass = (Class) actualTypeArguments[0];
- } else {
- throw new RuntimeException("can't instantiate collection field " + classname + " elements as they aren't a class");
- }
- } else {
- throw new RuntimeException("collection field " + classname + " must be genericised");
- }
- }
-
- return klass.getName();
- } catch (NoSuchFieldException e) {
- throw new RuntimeException("can't find field " + classname + " for node class " + currentNode.getClass().getName(), e);
- }
- }
- }
- }
-
- /**
- * Default impl, always returns 'id'
- */
- public static class DefaultIdentifierResolver implements IdentifierResolver {
- public String getIdentifierFor(String nodeName) {
- return "id";
- }
- }
-
- /**
- * Default impl that calls Class.newInstance()
- */
- public static class DefaultNewInstanceResolver implements NewInstanceResolver {
- public Object newInstance(Class klass, Map attributes) throws InstantiationException,
- IllegalAccessException {
- return klass.newInstance();
- }
- }
-
- /**
- * Default impl, always returns 'refId'
- */
- public static class DefaultReferenceResolver implements ReferenceResolver {
- public String getReferenceFor(String nodeName) {
- return "refId";
- }
- }
-
- /**
- * Default impl that returns parentName and childName accordingly.
- */
- public static class DefaultRelationNameResolver implements RelationNameResolver {
- /**
- * Handles the common English regular plurals with the following rules.
- * <ul>
- * <li>If childName ends in {consonant}y, replace 'y' with "ies". For example, allergy to allergies.</li>
- * <li>Otherwise, append 's'. For example, monkey to monkeys; employee to employees.</li>
- * </ul>
- * If the property does not exist then it will return childName unchanged.
- *
- * @see <a href="http://en.wikipedia.org/wiki/English_plural">English_plural</a>
- */
- public String resolveChildRelationName(String parentName, Object parent, String childName,
- Object child) {
- boolean matchesIESRule = PLURAL_IES_PATTERN.matcher(childName).matches();
- String childNamePlural = matchesIESRule ? childName.substring(0, childName.length() - 1) + "ies" : childName + "s";
-
- MetaProperty metaProperty = InvokerHelper.getMetaClass(parent)
- .hasProperty(parent, childNamePlural);
-
- return metaProperty != null ? childNamePlural : childName;
- }
-
- /**
- * Follow the most conventional pattern, returns the parentName
- * unchanged.
- */
- public String resolveParentRelationName(String parentName, Object parent,
- String childName, Object child) {
- return parentName;
- }
- }
-
- /**
- * Strategy for picking the correct synthetic identifier.
- */
- public interface IdentifierResolver {
- /**
- * Returns the name of the property that will identify the node.<br>
- *
- * @param nodeName the name of the node
- */
- String getIdentifierFor(String nodeName);
- }
-
- /**
- * Strategy for creating new instances of a class.<br>
- * Useful for plug-in calls to non-default constructors.
- */
- public interface NewInstanceResolver {
- /**
- * Create a new instance of Class klass.
- *
- * @param klass the resolved class name
- * @param attributes the attribute Map available for the node
- */
- Object newInstance(Class klass, Map attributes) throws InstantiationException,
- IllegalAccessException;
- }
-
- /**
- * Strategy for picking the correct synthetic reference identifier.
- */
- public interface ReferenceResolver {
- /**
- * Returns the name of the property that references another node.<br>
- *
- * @param nodeName the name of the node
- */
- String getReferenceFor(String nodeName);
- }
-
- /**
- * Strategy for resolving a relationship property name.
- */
- public interface RelationNameResolver {
- /**
- * Returns the mapping name of child -> parent
- *
- * @param parentName the name of the parent node
- * @param parent the parent node
- * @param childName the name of the child node
- * @param child the child node
- */
- String resolveChildRelationName(String parentName, Object parent, String childName,
- Object child);
-
- /**
- * Returns the mapping name of parent -> child
- *
- * @param parentName the name of the parent node
- * @param parent the parent node
- * @param childName the name of the child node
- * @param child the child node
- */
- String resolveParentRelationName(String parentName, Object parent, String childName,
- Object child);
- }
-
- private void resolveLazyReferences() {
- if (!lazyReferencesAllowed) return;
- for (NodeReference ref : lazyReferences) {
- if (ref.parent == null) continue;
-
- Object child = null;
- try {
- child = getProperty(ref.refId);
- } catch (MissingPropertyException mpe) {
- // ignore
- }
- if (child == null) {
- throw new IllegalArgumentException("There is no valid node for reference "
- + ref.parentName + "." + ref.childName + "=" + ref.refId);
- }
-
- // set child first
- childPropertySetter.setChild(ref.parent, child, ref.parentName,
- relationNameResolver.resolveChildRelationName(ref.parentName,
- ref.parent, ref.childName, child));
-
- // set parent afterwards
- String propertyName = relationNameResolver.resolveParentRelationName(ref.parentName,
- ref.parent, ref.childName, child);
- MetaProperty metaProperty = InvokerHelper.getMetaClass(child)
- .hasProperty(child, propertyName);
- if (metaProperty != null) {
- metaProperty.setProperty(child, ref.parent);
- }
- }
- }
-
- private static String makeClassName(String root, String name) {
- return root + "." + name.substring(0, 1).toUpperCase() + name.substring(1);
- }
-
- private static class ObjectFactory extends AbstractFactory {
- public Object newInstance(FactoryBuilderSupport builder, Object name, Object value,
- Map properties) throws InstantiationException, IllegalAccessException {
- ObjectGraphBuilder ogbuilder = (ObjectGraphBuilder) builder;
- String classname = ogbuilder.classNameResolver.resolveClassname((String) name);
- Class klass = resolveClass(builder, classname, name, value, properties);
- Map context = builder.getContext();
- context.put(ObjectGraphBuilder.NODE_NAME, name);
- context.put(ObjectGraphBuilder.NODE_CLASS, klass);
- return resolveInstance(builder, name, value, klass, properties);
- }
-
- protected Class resolveClass(FactoryBuilderSupport builder, String classname, Object name, Object value,
- Map properties) {
- ObjectGraphBuilder ogbuilder = (ObjectGraphBuilder) builder;
- Class klass = ogbuilder.resolvedClasses.get(classname);
- if (klass == null) {
- klass = loadClass(ogbuilder.classLoader, classname);
- if (klass == null) {
- klass = loadClass(ogbuilder.getClass().getClassLoader(), classname);
- }
- if (klass == null) {
- try {
- klass = Class.forName(classname);
- } catch (ClassNotFoundException e) {
- // ignore
- }
- }
- if (klass == null) {
- klass = loadClass(Thread.currentThread().getContextClassLoader(), classname);
- }
- if (klass == null) {
- throw new RuntimeException(new ClassNotFoundException(classname));
- }
- ogbuilder.resolvedClasses.put(classname, klass);
- }
-
- return klass;
- }
-
- protected Object resolveInstance(FactoryBuilderSupport builder, Object name, Object value, Class klass,
- Map properties) throws InstantiationException, IllegalAccessException {
- ObjectGraphBuilder ogbuilder = (ObjectGraphBuilder) builder;
- if (value != null && klass.isAssignableFrom(value.getClass())) {
- return value;
- }
-
- return ogbuilder.newInstanceResolver.newInstance(klass, properties);
- }
-
- public void setChild(FactoryBuilderSupport builder, Object parent, Object child) {
- if (child == null) return;
-
- ObjectGraphBuilder ogbuilder = (ObjectGraphBuilder) builder;
- if (parent != null) {
- Map context = ogbuilder.getContext();
- Map parentContext = ogbuilder.getParentContext();
-
- String parentName = null;
- String childName = (String) context.get(NODE_NAME);
- if (parentContext != null) {
- parentName = (String) parentContext.get(NODE_NAME);
- }
-
- String propertyName = ogbuilder.relationNameResolver.resolveParentRelationName(
- parentName, parent, childName, child);
- MetaProperty metaProperty = InvokerHelper.getMetaClass(child)
- .hasProperty(child, propertyName);
- if (metaProperty != null) {
- metaProperty.setProperty(child, parent);
- }
- }
- }
-
- public void setParent(FactoryBuilderSupport builder, Object parent, Object child) {
- if (child == null) return;
-
- ObjectGraphBuilder ogbuilder = (ObjectGraphBuilder) builder;
- if (parent != null) {
- Map context = ogbuilder.getContext();
- Map parentContext = ogbuilder.getParentContext();
-
- String parentName = null;
- String childName = (String) context.get(NODE_NAME);
- if (parentContext != null) {
- parentName = (String) parentContext.get(NODE_NAME);
- }
-
- ogbuilder.childPropertySetter.setChild(parent, child, parentName,
- ogbuilder.relationNameResolver.resolveChildRelationName(parentName,
- parent, childName, child));
- }
- }
-
- protected Class loadClass(ClassLoader classLoader, String classname) {
- if (classLoader == null || classname == null) {
- return null;
- }
- try {
- return classLoader.loadClass(classname);
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
- }
-
- private static class ObjectBeanFactory extends ObjectFactory {
- public Object newInstance(FactoryBuilderSupport builder, Object name, Object value,
- Map properties) throws InstantiationException, IllegalAccessException {
- if(value == null) return super.newInstance(builder, name, value, properties);
-
- Object bean = null;
- Class klass = null;
- Map context = builder.getContext();
- if(value instanceof String || value instanceof GString) {
- /*
- String classname = value.toString();
- klass = resolveClass(builder, classname, name, value, properties);
- bean = resolveInstance(builder, name, value, klass, properties);
- */
- throw new IllegalArgumentException("ObjectGraphBuilder."+((ObjectGraphBuilder)builder).getBeanFactoryName()+"() does not accept String nor GString as value.");
- } else if(value instanceof Class) {
- klass = (Class) value;
- bean = resolveInstance(builder, name, value, klass, properties);
- } else {
- klass = value.getClass();
- bean = value;
- }
-
- String nodename = klass.getSimpleName();
- if(nodename.length() > 1) {
- nodename = nodename.substring(0, 1).toLowerCase() + nodename.substring(1);
- } else {
- nodename = nodename.toLowerCase();
- }
- context.put(ObjectGraphBuilder.NODE_NAME, nodename);
- context.put(ObjectGraphBuilder.NODE_CLASS, klass);
- return bean;
- }
- }
-
- private static class ObjectRefFactory extends ObjectFactory {
- public boolean isLeaf() {
- return true;
- }
-
- public Object newInstance(FactoryBuilderSupport builder, Object name, Object value,
- Map properties) throws InstantiationException, IllegalAccessException {
- ObjectGraphBuilder ogbuilder = (ObjectGraphBuilder) builder;
- String refProperty = ogbuilder.referenceResolver.getReferenceFor((String) name);
- Object refId = properties.remove(refProperty);
-
- Object object = null;
- Boolean lazy = Boolean.FALSE;
- if (refId instanceof String) {
- try {
- object = ogbuilder.getProperty((String) refId);
- } catch (MissingPropertyException mpe) {
- // ignore, will try lazy reference
- }
- if (object == null) {
- if (ogbuilder.isLazyReferencesAllowed()) {
- lazy = Boolean.TRUE;
- } else {
- throw new IllegalArgumentException("There is no previous node with "
- + ogbuilder.identifierResolver.getIdentifierFor((String) name) + "="
- + refId);
- }
- }
- } else {
- // assume we got a true reference to the object
- object = refId;
- }
-
- if (!properties.isEmpty()) {
- throw new IllegalArgumentException(
- "You can not modify the properties of a referenced object.");
- }
-
- Map context = ogbuilder.getContext();
- context.put(ObjectGraphBuilder.NODE_NAME, name);
- context.put(ObjectGraphBuilder.LAZY_REF, lazy);
-
- if (lazy.booleanValue()) {
- Map parentContext = ogbuilder.getParentContext();
-
- Object parent = null;
- String parentName = null;
- String childName = (String) name;
- if (parentContext != null) {
- parent = context.get(CURRENT_NODE);
- parentName = (String) parentContext.get(NODE_NAME);
- }
- ogbuilder.lazyReferences.add(new NodeReference(parent,
- parentName,
- childName,
- (String) refId));
- } else {
- context.put(ObjectGraphBuilder.NODE_CLASS, object.getClass());
- }
-
- return object;
- }
-
- public void setChild(FactoryBuilderSupport builder, Object parent, Object child) {
- Boolean lazy = (Boolean) builder.getContext().get(ObjectGraphBuilder.LAZY_REF);
- if (!lazy.booleanValue()) super.setChild(builder, parent, child);
- }
-
- public void setParent(FactoryBuilderSupport builder, Object parent, Object child) {
- Boolean lazy = (Boolean) builder.getContext().get(ObjectGraphBuilder.LAZY_REF);
- if (!lazy.booleanValue()) super.setParent(builder, parent, child);
- }
- }
-
- private static final class NodeReference {
- private final Object parent;
- private final String parentName;
- private final String childName;
- private final String refId;
-
- private NodeReference(Object parent, String parentName, String childName, String refId) {
- this.parent = parent;
- this.parentName = parentName;
- this.childName = childName;
- this.refId = refId;
- }
-
- public String toString() {
- return new StringBuilder().append("[parentName=").append(parentName)
- .append(", childName=").append(childName)
- .append(", refId=").append(refId)
- .append("]").toString();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/util/ObservableList.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/ObservableList.java b/src/main/groovy/util/ObservableList.java
deleted file mode 100644
index 31b5745..0000000
--- a/src/main/groovy/util/ObservableList.java
+++ /dev/null
@@ -1,570 +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 java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-
-/**
- * List decorator that will trigger PropertyChangeEvents when a value changes.<br>
- * An optional Closure may be specified and will work as a filter, if it returns true the property
- * will trigger an event (if the value indeed changed), otherwise it won't. The Closure may receive
- * 1 or 2 parameters, the single one being the value, the other one both the key and value, for
- * example:
- * <pre>
- * // skip all properties whose value is a closure
- * def map = new ObservableList( {!(it instanceof Closure)} )
- *
- * // skip all properties whose name matches a regex
- * def map = new ObservableList( { name, value -> !(name =˜ /[A-Z+]/) } )
- * </pre>
- * The current implementation will trigger specialized events in the following scenarios, you need
- * not register a different listener as those events extend from PropertyChangeEvent
- * <ul>
- * <li>ObservableList.ElementAddedEvent - a new element is added to the list</li>
- * <li>ObservableList.ElementRemovedEvent - an element is removed from the list</li>
- * <li>ObservableList.ElementUpdatedEvent - an element changes value (same as regular
- * PropertyChangeEvent)</li>
- * <li>ObservableList.ElementClearedEvent - all elements have been removed from the list</li>
- * <li>ObservableList.MultiElementAddedEvent - triggered by calling list.addAll()</li>
- * <li>ObservableList.MultiElementRemovedEvent - triggered by calling
- * list.removeAll()/list.retainAll()</li>
- * </ul>
- * <p>
- * <strong>Bound properties</strong>
- * <ul>
- * <li><tt>content</tt> - read-only.</li>
- * <li><tt>size</tt> - read-only.</li>
- * </ul>
- *
- * @author <a href="mailto:aalmiray@users.sourceforge.net">Andres Almiray</a>
- */
-public class ObservableList implements List {
- private final List delegate;
- private final PropertyChangeSupport pcs;
- private final Closure test;
-
- public static final String SIZE_PROPERTY = "size";
- public static final String CONTENT_PROPERTY = "content";
-
- public ObservableList() {
- this(new ArrayList(), null);
- }
-
- public ObservableList(List delegate) {
- this(delegate, null);
- }
-
- public ObservableList(Closure test) {
- this(new ArrayList(), test);
- }
-
- public ObservableList(List delegate, Closure test) {
- this.delegate = delegate;
- this.test = test;
- pcs = new PropertyChangeSupport(this);
- }
-
- public List getContent() {
- return Collections.unmodifiableList(delegate);
- }
-
- protected List getDelegateList() {
- return delegate;
- }
-
- protected Closure getTest() {
- return test;
- }
-
- protected void fireElementAddedEvent(int index, Object element) {
- fireElementEvent(new ElementAddedEvent(this, element, index));
- }
-
- protected void fireMultiElementAddedEvent(int index, List values) {
- fireElementEvent(new MultiElementAddedEvent(this, index, values));
- }
-
- protected void fireElementClearedEvent(List values) {
- fireElementEvent(new ElementClearedEvent(this, values));
- }
-
- protected void fireElementRemovedEvent(int index, Object element) {
- fireElementEvent(new ElementRemovedEvent(this, element, index));
- }
-
- protected void fireMultiElementRemovedEvent(List values) {
- fireElementEvent(new MultiElementRemovedEvent(this, values));
- }
-
- protected void fireElementUpdatedEvent(int index, Object oldValue, Object newValue) {
- fireElementEvent(new ElementUpdatedEvent(this, oldValue, newValue, index));
- }
-
- protected void fireElementEvent(ElementEvent event) {
- pcs.firePropertyChange(event);
- }
-
- protected void fireSizeChangedEvent(int oldValue, int newValue) {
- pcs.firePropertyChange(new PropertyChangeEvent(this, SIZE_PROPERTY, oldValue, newValue));
- }
-
- public void add(int index, Object element) {
- int oldSize = size();
- delegate.add(index, element);
- fireAddWithTest(element, index, oldSize);
- }
-
- public boolean add(Object o) {
- int oldSize = size();
- boolean success = delegate.add(o);
- if (success) {
- fireAddWithTest(o, oldSize, oldSize);
- }
- return success;
- }
-
- private void fireAddWithTest(Object element, int index, int oldSize) {
- if (test != null) {
- Object result = test.call(element);
- if (result != null && result instanceof Boolean && (Boolean) result) {
- fireElementAddedEvent(index, element);
- fireSizeChangedEvent(oldSize, size());
- }
- } else {
- fireElementAddedEvent(index, element);
- fireSizeChangedEvent(oldSize, size());
- }
- }
-
- public boolean addAll(Collection c) {
- return addAll(size(), c);
- }
-
- public boolean addAll(int index, Collection c) {
- int oldSize = size();
- boolean success = delegate.addAll(index, c);
-
- if (success && c != null) {
- List values = new ArrayList();
- for (Object element : c) {
- if (test != null) {
- Object result = test.call(element);
- if (result != null && result instanceof Boolean && (Boolean) result) {
- values.add(element);
- }
- } else {
- values.add(element);
- }
- }
- if (!values.isEmpty()) {
- fireMultiElementAddedEvent(index, values);
- fireSizeChangedEvent(oldSize, size());
- }
- }
-
- return success;
- }
-
- public void clear() {
- int oldSize = size();
- List values = new ArrayList();
- values.addAll(delegate);
- delegate.clear();
- if (!values.isEmpty()) {
- fireElementClearedEvent(values);
- }
- fireSizeChangedEvent(oldSize, size());
- }
-
- public boolean contains(Object o) {
- return delegate.contains(o);
- }
-
- public boolean containsAll(Collection c) {
- return delegate.containsAll(c);
- }
-
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
-
- public Object get(int index) {
- return delegate.get(index);
- }
-
- public int hashCode() {
- return delegate.hashCode();
- }
-
- public int indexOf(Object o) {
- return delegate.indexOf(o);
- }
-
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- public Iterator iterator() {
- return new ObservableIterator(delegate.iterator());
- }
-
- public int lastIndexOf(Object o) {
- return delegate.lastIndexOf(o);
- }
-
- public ListIterator listIterator() {
- return new ObservableListIterator(delegate.listIterator(), 0);
- }
-
- public ListIterator listIterator(int index) {
- return new ObservableListIterator(delegate.listIterator(index), index);
- }
-
- public Object remove(int index) {
- int oldSize = size();
- Object element = delegate.remove(index);
- fireElementRemovedEvent(index, element);
- fireSizeChangedEvent(oldSize, size());
- return element;
- }
-
- public boolean remove(Object o) {
- int oldSize = size();
- int index = delegate.indexOf(o);
- boolean success = delegate.remove(o);
- if (success) {
- fireElementRemovedEvent(index, o);
- fireSizeChangedEvent(oldSize, size());
- }
- return success;
- }
-
- public boolean removeAll(Collection c) {
- if (c == null) {
- return false;
- }
-
- List values = new ArrayList();
- // GROOVY-7783 use Sets for O(1) performance for contains
- Set delegateSet = new HashSet<Object>(delegate);
- if (!(c instanceof Set)) {
- c = new HashSet<Object>(c);
- }
- for (Object element : c) {
- if (delegateSet.contains(element)) {
- values.add(element);
- }
- }
-
- int oldSize = size();
- boolean success = delegate.removeAll(c);
- if (success && !values.isEmpty()) {
- fireMultiElementRemovedEvent(values);
- fireSizeChangedEvent(oldSize, size());
- }
-
- return success;
- }
-
- public boolean retainAll(Collection c) {
- if (c == null) {
- return false;
- }
-
- List values = new ArrayList();
- // GROOVY-7783 use Set for O(1) performance for contains
- if (!(c instanceof Set)) {
- c = new HashSet<Object>(c);
- }
- for (Object element : delegate) {
- if (!c.contains(element)) {
- values.add(element);
- }
- }
-
- int oldSize = size();
- boolean success = delegate.retainAll(c);
- if (success && !values.isEmpty()) {
- fireMultiElementRemovedEvent(values);
- fireSizeChangedEvent(oldSize, size());
- }
-
- return success;
- }
-
- public Object set(int index, Object element) {
- Object oldValue = delegate.set(index, element);
- if (test != null) {
- Object result = test.call(element);
- if (result != null && result instanceof Boolean && ((Boolean) result).booleanValue()) {
- fireElementUpdatedEvent(index, oldValue, element);
- }
- } else {
- fireElementUpdatedEvent(index, oldValue, element);
- }
- return oldValue;
- }
-
- public int size() {
- return delegate.size();
- }
-
- public int getSize() {
- return size();
- }
-
- public List subList(int fromIndex, int toIndex) {
- return delegate.subList(fromIndex, toIndex);
- }
-
- public Object[] toArray() {
- return delegate.toArray();
- }
-
- public Object[] toArray(Object[] a) {
- return delegate.toArray(a);
- }
-
- protected class ObservableIterator implements Iterator {
- private final Iterator iterDelegate;
- protected int cursor = -1 ;
-
- public ObservableIterator(Iterator iterDelegate) {
- this.iterDelegate = iterDelegate;
- }
-
- public Iterator getDelegate() {
- return iterDelegate;
- }
-
- public boolean hasNext() {
- return iterDelegate.hasNext();
- }
-
- public Object next() {
- cursor++;
- return iterDelegate.next();
- }
-
- public void remove() {
- int oldSize = ObservableList.this.size();
- Object element = ObservableList.this.get(cursor);
- iterDelegate.remove();
- fireElementRemovedEvent(cursor, element);
- fireSizeChangedEvent(oldSize, size());
- cursor--;
- }
- }
-
- protected class ObservableListIterator extends ObservableIterator implements ListIterator {
- public ObservableListIterator(ListIterator iterDelegate, int index) {
- super(iterDelegate);
- cursor = index - 1;
- }
-
- public ListIterator getListIterator() {
- return (ListIterator) getDelegate();
- }
-
- public void add(Object o) {
- ObservableList.this.add(o);
- cursor++;
- }
-
- public boolean hasPrevious() {
- return getListIterator().hasPrevious();
- }
-
- public int nextIndex() {
- return getListIterator().nextIndex();
- }
-
- public Object previous() {
- return getListIterator().previous();
- }
-
- public int previousIndex() {
- return getListIterator().previousIndex();
- }
-
- public void set(Object o) {
- ObservableList.this.set(cursor, o);
- }
- }
-
- // observable interface
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public PropertyChangeListener[] getPropertyChangeListeners() {
- return pcs.getPropertyChangeListeners();
- }
-
- public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
- return pcs.getPropertyChangeListeners(propertyName);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
- public boolean hasListeners(String propertyName) {
- return pcs.hasListeners(propertyName);
- }
-
- public enum ChangeType {
- ADDED, UPDATED, REMOVED, CLEARED, MULTI_ADD, MULTI_REMOVE, NONE;
-
- public static final Object oldValue = new Object();
- public static final Object newValue = new Object();
-
- public static ChangeType resolve(int ordinal) {
- switch (ordinal) {
- case 0:
- return ADDED;
- case 2:
- return REMOVED;
- case 3:
- return CLEARED;
- case 4:
- return MULTI_ADD;
- case 5:
- return MULTI_REMOVE;
- case 6:
- return NONE;
- case 1:
- default:
- return UPDATED;
- }
- }
- }
-
- public abstract static class ElementEvent extends PropertyChangeEvent {
-
- private final ChangeType type;
- private final int index;
-
- public ElementEvent(Object source, Object oldValue, Object newValue, int index, ChangeType type) {
- super(source, ObservableList.CONTENT_PROPERTY, oldValue, newValue);
- this.type = type;
- this.index = index;
- }
-
- public int getIndex() {
- return index;
- }
-
- public int getType() {
- return type.ordinal();
- }
-
- public ChangeType getChangeType() {
- return type;
- }
-
- public String getTypeAsString() {
- return type.name().toUpperCase();
- }
- }
-
- public static class ElementAddedEvent extends ElementEvent {
- public ElementAddedEvent(Object source, Object newValue, int index) {
- super(source, null, newValue, index, ChangeType.ADDED);
- }
- }
-
- public static class ElementUpdatedEvent extends ElementEvent {
- public ElementUpdatedEvent(Object source, Object oldValue, Object newValue, int index) {
- super(source, oldValue, newValue, index, ChangeType.UPDATED);
- }
- }
-
- public static class ElementRemovedEvent extends ElementEvent {
- public ElementRemovedEvent(Object source, Object value, int index) {
- super(source, value, null, index, ChangeType.REMOVED);
- }
- }
-
- public static class ElementClearedEvent extends ElementEvent {
- private final List values = new ArrayList();
-
- public ElementClearedEvent(Object source, List values) {
- super(source, ChangeType.oldValue, ChangeType.newValue, 0, ChangeType.CLEARED);
- if (values != null) {
- this.values.addAll(values);
- }
- }
-
- public List getValues() {
- return Collections.unmodifiableList(values);
- }
- }
-
- public static class MultiElementAddedEvent extends ElementEvent {
- private final List values = new ArrayList();
-
- public MultiElementAddedEvent(Object source, int index, List values) {
- super(source, ChangeType.oldValue, ChangeType.newValue, index, ChangeType.MULTI_ADD);
- if (values != null) {
- this.values.addAll(values);
- }
- }
-
- public List getValues() {
- return Collections.unmodifiableList(values);
- }
- }
-
- public static class MultiElementRemovedEvent extends ElementEvent {
- private final List values = new ArrayList();
-
- public MultiElementRemovedEvent(Object source, List values) {
- super(source, ChangeType.oldValue, ChangeType.newValue, 0, ChangeType.MULTI_REMOVE);
- if (values != null) {
- this.values.addAll(values);
- }
- }
-
- public List getValues() {
- return Collections.unmodifiableList(values);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/util/ObservableMap.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/ObservableMap.java b/src/main/groovy/util/ObservableMap.java
deleted file mode 100644
index 43dc7a0..0000000
--- a/src/main/groovy/util/ObservableMap.java
+++ /dev/null
@@ -1,410 +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 java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Map decorator that will trigger PropertyChangeEvents when a value changes.<br>
- * An optional Closure may be specified and will work as a filter, if it returns
- * true the property will trigger an event (if the value indeed changed),
- * otherwise it won't. The Closure may receive 1 or 2 parameters, the single one
- * being the value, the other one both the key and value, for example:
- * <pre>
- * // skip all properties whose value is a closure
- * def map = new ObservableMap( {!(it instanceof Closure)} )
- *
- * // skip all properties whose name matches a regex
- * def map = new ObservableMap( { name, value -> !(name =~ /[A-Z+]/) } )
- * </pre>
- * The current implementation will trigger specialized events in the following scenarios,
- * you need not register a different listener as those events extend from PropertyChangeEvent
- * <ul>
- * <li>ObservableMap.PropertyAddedEvent - a new property is added to the map</li>
- * <li>ObservableMap.PropertyRemovedEvent - a property is removed from the map</li>
- * <li>ObservableMap.PropertyUpdatedEvent - a property changes value (same as regular PropertyChangeEvent)</li>
- * <li>ObservableMap.PropertyClearedEvent - all properties have been removed from the map</li>
- * <li>ObservableMap.MultiPropertyEvent - triggered by calling map.putAll(), contains Added|Updated events</li>
- * </ul>
- * <p>
- * <strong>Bound properties</strong>
- * <ul>
- * <li><tt>content</tt> - read-only.</li>
- * <li><tt>size</tt> - read-only.</li>
- * </ul>
- *
- * @author <a href="mailto:aalmiray@users.sourceforge.net">Andres Almiray</a>
- */
-public class ObservableMap implements Map {
- private final Map delegate;
- private final PropertyChangeSupport pcs;
- private final Closure test;
-
- public static final String SIZE_PROPERTY = "size";
- public static final String CONTENT_PROPERTY = "content";
- public static final String CLEARED_PROPERTY = "cleared";
-
- public ObservableMap() {
- this(new LinkedHashMap(), null);
- }
-
- public ObservableMap(Closure test) {
- this(new LinkedHashMap(), test);
- }
-
- public ObservableMap(Map delegate) {
- this(delegate, null);
- }
-
- public ObservableMap(Map delegate, Closure test) {
- this.delegate = delegate;
- this.test = test;
- pcs = new PropertyChangeSupport(this);
- }
-
- protected Map getMapDelegate() {
- return delegate;
- }
-
- protected Closure getTest() {
- return test;
- }
-
- public Map getContent() {
- return Collections.unmodifiableMap(delegate);
- }
-
- protected void firePropertyClearedEvent(Map values) {
- firePropertyEvent(new PropertyClearedEvent(this, values));
- }
-
- protected void firePropertyAddedEvent(Object key, Object value) {
- firePropertyEvent(new PropertyAddedEvent(this, String.valueOf(key), value));
- }
-
- protected void firePropertyUpdatedEvent(Object key, Object oldValue, Object newValue) {
- firePropertyEvent(new PropertyUpdatedEvent(this, String.valueOf(key), oldValue, newValue));
- }
-
- protected void fireMultiPropertyEvent(List<PropertyEvent> events) {
- firePropertyEvent(new MultiPropertyEvent(this, (PropertyEvent[]) events.toArray(new PropertyEvent[events.size()])));
- }
-
- protected void fireMultiPropertyEvent(PropertyEvent[] events) {
- firePropertyEvent(new MultiPropertyEvent(this, events));
- }
-
- protected void firePropertyRemovedEvent(Object key, Object value) {
- firePropertyEvent(new PropertyRemovedEvent(this, String.valueOf(key), value));
- }
-
- protected void firePropertyEvent(PropertyEvent event) {
- pcs.firePropertyChange(event);
- }
-
- protected void fireSizeChangedEvent(int oldValue, int newValue) {
- pcs.firePropertyChange(new PropertyChangeEvent(this, SIZE_PROPERTY, oldValue, newValue));
- }
-
- // Map interface
-
- public void clear() {
- int oldSize = size();
- Map values = new HashMap();
- if (!delegate.isEmpty()) {
- values.putAll(delegate);
- }
- delegate.clear();
- firePropertyClearedEvent(values);
- fireSizeChangedEvent(oldSize, size());
- }
-
- public boolean containsKey(Object key) {
- return delegate.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return delegate.containsValue(value);
- }
-
- public Set entrySet() {
- return delegate.entrySet();
- }
-
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
-
- public Object get(Object key) {
- return delegate.get(key);
- }
-
- public int hashCode() {
- return delegate.hashCode();
- }
-
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- public Set keySet() {
- return delegate.keySet();
- }
-
- public Object put(Object key, Object value) {
- int oldSize = size();
- Object oldValue = null;
- boolean newKey = !delegate.containsKey(key);
- if (test != null) {
- oldValue = delegate.put(key, value);
- Object result = null;
- if (test.getMaximumNumberOfParameters() == 2) {
- result = test.call(new Object[]{key, value});
- } else {
- result = test.call(value);
- }
- if (result != null && result instanceof Boolean && (Boolean) result) {
- if (newKey) {
- firePropertyAddedEvent(key, value);
- fireSizeChangedEvent(oldSize, size());
- } else if (oldValue != value) {
- firePropertyUpdatedEvent(key, oldValue, value);
- }
- }
- } else {
- oldValue = delegate.put(key, value);
- if (newKey) {
- firePropertyAddedEvent(key, value);
- fireSizeChangedEvent(oldSize, size());
- } else if (oldValue != value) {
- firePropertyUpdatedEvent(key, oldValue, value);
- }
- }
- return oldValue;
- }
-
- public void putAll(Map map) {
- int oldSize = size();
- if (map != null) {
- List<PropertyEvent> events = new ArrayList<PropertyEvent>();
- for (Object o : map.entrySet()) {
- Entry entry = (Entry) o;
-
- String key = String.valueOf(entry.getKey());
- Object newValue = entry.getValue();
- Object oldValue = null;
-
- boolean newKey = !delegate.containsKey(key);
- if (test != null) {
- oldValue = delegate.put(key, newValue);
- Object result = null;
- if (test.getMaximumNumberOfParameters() == 2) {
- result = test.call(new Object[]{key, newValue});
- } else {
- result = test.call(newValue);
- }
- if (result != null && result instanceof Boolean && (Boolean) result) {
- if (newKey) {
- events.add(new PropertyAddedEvent(this, key, newValue));
- } else if (oldValue != newValue) {
- events.add(new PropertyUpdatedEvent(this, key, oldValue, newValue));
- }
- }
- } else {
- oldValue = delegate.put(key, newValue);
- if (newKey) {
- events.add(new PropertyAddedEvent(this, key, newValue));
- } else if (oldValue != newValue) {
- events.add(new PropertyUpdatedEvent(this, key, oldValue, newValue));
- }
- }
- }
- if (!events.isEmpty()) {
- fireMultiPropertyEvent(events);
- fireSizeChangedEvent(oldSize, size());
- }
- }
- }
-
- public Object remove(Object key) {
- int oldSize = size();
- Object result = delegate.remove(key);
- if (key != null) {
- firePropertyRemovedEvent(key, result);
- fireSizeChangedEvent(oldSize, size());
- }
- return result;
- }
-
- public int size() {
- return delegate.size();
- }
-
- public int getSize() {
- return size();
- }
-
- public Collection values() {
- return delegate.values();
- }
-
- // observable interface
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public PropertyChangeListener[] getPropertyChangeListeners() {
- return pcs.getPropertyChangeListeners();
- }
-
- public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
- return pcs.getPropertyChangeListeners(propertyName);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
- public boolean hasListeners(String propertyName) {
- return pcs.hasListeners(propertyName);
- }
-
- public enum ChangeType {
- ADDED, UPDATED, REMOVED, CLEARED, MULTI, NONE;
-
- public static final Object oldValue = new Object();
- public static final Object newValue = new Object();
-
- public static ChangeType resolve(int ordinal) {
- switch (ordinal) {
- case 0:
- return ADDED;
- case 2:
- return REMOVED;
- case 3:
- return CLEARED;
- case 4:
- return MULTI;
- case 5:
- return NONE;
- case 1:
- default:
- return UPDATED;
- }
- }
- }
-
- public abstract static class PropertyEvent extends PropertyChangeEvent {
- private final ChangeType type;
-
- public PropertyEvent(Object source, String propertyName, Object oldValue, Object newValue, ChangeType type) {
- super(source, propertyName, oldValue, newValue);
- this.type = type;
- }
-
- public int getType() {
- return type.ordinal();
- }
-
- public ChangeType getChangeType() {
- return type;
- }
-
- public String getTypeAsString() {
- return type.name().toUpperCase();
- }
- }
-
- public static class PropertyAddedEvent extends PropertyEvent {
- public PropertyAddedEvent(Object source, String propertyName, Object newValue) {
- super(source, propertyName, null, newValue, ChangeType.ADDED);
- }
- }
-
- public static class PropertyUpdatedEvent extends PropertyEvent {
- public PropertyUpdatedEvent(Object source, String propertyName, Object oldValue, Object newValue) {
- super(source, propertyName, oldValue, newValue, ChangeType.UPDATED);
- }
- }
-
- public static class PropertyRemovedEvent extends PropertyEvent {
- public PropertyRemovedEvent(Object source, String propertyName, Object oldValue) {
- super(source, propertyName, oldValue, null, ChangeType.REMOVED);
- }
- }
-
- public static class PropertyClearedEvent extends PropertyEvent {
- private final Map values = new HashMap();
-
- public PropertyClearedEvent(Object source, Map values) {
- super(source, ObservableMap.CLEARED_PROPERTY, values, null, ChangeType.CLEARED);
- if (values != null) {
- this.values.putAll(values);
- }
- }
-
- public Map getValues() {
- return Collections.unmodifiableMap(values);
- }
- }
-
- public static class MultiPropertyEvent extends PropertyEvent {
- public static final String MULTI_PROPERTY = "groovy_util_ObservableMap_MultiPropertyEvent_MULTI";
- private static final PropertyEvent[] EMPTY_PROPERTY_EVENTS = new PropertyEvent[0];
-
- private final PropertyEvent[] events;
-
- public MultiPropertyEvent(Object source, PropertyEvent[] events) {
- super(source, MULTI_PROPERTY, ChangeType.oldValue, ChangeType.newValue, ChangeType.MULTI);
- if (events != null && events.length > 0) {
- this.events = new PropertyEvent[events.length];
- System.arraycopy(events, 0, this.events, 0, events.length);
- } else {
- this.events = EMPTY_PROPERTY_EVENTS;
- }
- }
-
- public PropertyEvent[] getEvents() {
- PropertyEvent[] copy = new PropertyEvent[events.length];
- System.arraycopy(events, 0, copy, 0, events.length);
- return copy;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/util/ObservableSet.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/ObservableSet.java b/src/main/groovy/util/ObservableSet.java
deleted file mode 100644
index b794436..0000000
--- a/src/main/groovy/util/ObservableSet.java
+++ /dev/null
@@ -1,427 +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 java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.Stack;
-
-/**
- * Set decorator that will trigger PropertyChangeEvents when a value changes.<br>
- * An optional Closure may be specified and will work as a filter, if it returns true the property
- * will trigger an event (if the value indeed changed), otherwise it won't. The Closure may receive
- * 1 or 2 parameters, the single one being the value, the other one both the key and value, for
- * example:
- * <pre>
- * // skip all properties whose value is a closure
- * def set = new ObservableSet( {!(it instanceof Closure)} )
- * <p/>
- * // skip all properties whose name matches a regex
- * def set = new ObservableSet( { name, value -> !(name =˜ /[A-Z+]/) } )
- * </pre>
- * The current implementation will trigger specialized events in the following scenarios, you need
- * not register a different listener as those events extend from PropertyChangeEvent
- * <ul>
- * <li>ObservableSet.ElementAddedEvent - a new element is added to the set</li>
- * <li>ObservableSet.ElementRemovedEvent - an element is removed from the set</li>
- * <li>ObservableSet.ElementUpdatedEvent - an element changes value (same as regular
- * PropertyChangeEvent)</li>
- * <li>ObservableSet.ElementClearedEvent - all elements have been removed from the list</li>
- * <li>ObservableSet.MultiElementAddedEvent - triggered by calling set.addAll()</li>
- * <li>ObservableSet.MultiElementRemovedEvent - triggered by calling
- * set.removeAll()/set.retainAll()</li>
- * </ul>
- *
- * <p>
- * <strong>Bound properties</strong>
- * <ul>
- * <li><tt>content</tt> - read-only.</li>
- * <li><tt>size</tt> - read-only.</li>
- * </ul>
- *
- * @author <a href="mailto:aalmiray@users.sourceforge.net">Andres Almiray</a>
- */
-public class ObservableSet<E> implements Set<E> {
- private final Set<E> delegate;
- private final PropertyChangeSupport pcs;
- private final Closure test;
-
- public static final String SIZE_PROPERTY = "size";
- public static final String CONTENT_PROPERTY = "content";
-
- public ObservableSet() {
- this(new HashSet<E>(), null);
- }
-
- public ObservableSet(Set<E> delegate) {
- this(delegate, null);
- }
-
- public ObservableSet(Closure test) {
- this(new HashSet<E>(), test);
- }
-
- public ObservableSet(Set<E> delegate, Closure test) {
- this.delegate = delegate;
- this.test = test;
- this.pcs = new PropertyChangeSupport(this);
- }
-
- public Set<E> getContent() {
- return Collections.unmodifiableSet(delegate);
- }
-
- protected Set<E> getDelegateSet() {
- return delegate;
- }
-
- protected Closure getTest() {
- return test;
- }
-
- protected void fireElementAddedEvent(Object element) {
- fireElementEvent(new ElementAddedEvent(this, element));
- }
-
- protected void fireMultiElementAddedEvent(List values) {
- fireElementEvent(new MultiElementAddedEvent(this, values));
- }
-
- protected void fireElementClearedEvent(List values) {
- fireElementEvent(new ElementClearedEvent(this, values));
- }
-
- protected void fireElementRemovedEvent(Object element) {
- fireElementEvent(new ElementRemovedEvent(this, element));
- }
-
- protected void fireMultiElementRemovedEvent(List values) {
- fireElementEvent(new MultiElementRemovedEvent(this, values));
- }
-
- protected void fireElementEvent(ElementEvent event) {
- pcs.firePropertyChange(event);
- }
-
- protected void fireSizeChangedEvent(int oldValue, int newValue) {
- pcs.firePropertyChange(new PropertyChangeEvent(this, SIZE_PROPERTY, oldValue, newValue));
- }
-
- // observable interface
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public PropertyChangeListener[] getPropertyChangeListeners() {
- return pcs.getPropertyChangeListeners();
- }
-
- public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
- return pcs.getPropertyChangeListeners(propertyName);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
- public boolean hasListeners(String propertyName) {
- return pcs.hasListeners(propertyName);
- }
-
- public int size() {
- return delegate.size();
- }
-
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- public boolean contains(Object o) {
- return delegate.contains(o);
- }
-
- public Iterator<E> iterator() {
- return new ObservableIterator<E>(delegate.iterator());
- }
-
- public Object[] toArray() {
- return delegate.toArray();
- }
-
- public <T> T[] toArray(T[] ts) {
- return (T[]) delegate.toArray(ts);
- }
-
- public boolean add(E e) {
- int oldSize = size();
- boolean success = delegate.add(e);
- if (success) {
- if (test != null) {
- Object result = test.call(e);
- if (result != null && result instanceof Boolean && (Boolean) result) {
- fireElementAddedEvent(e);
- fireSizeChangedEvent(oldSize, size());
- }
- } else {
- fireElementAddedEvent(e);
- fireSizeChangedEvent(oldSize, size());
- }
- }
- return success;
- }
-
- public boolean remove(Object o) {
- int oldSize = size();
- boolean success = delegate.remove(o);
- if (success) {
- fireElementRemovedEvent(o);
- fireSizeChangedEvent(oldSize, size());
- }
- return success;
- }
-
- public boolean containsAll(Collection<?> objects) {
- return delegate.containsAll(objects);
- }
-
- public boolean addAll(Collection<? extends E> c) {
- Set<E> duplicates = new HashSet<E>();
- if (null != c) {
- for (E e : c) {
- if (!delegate.contains(e)) continue;
- duplicates.add(e);
- }
- }
-
- int oldSize = size();
- boolean success = delegate.addAll(c);
-
- if (success && c != null) {
- List<E> values = new ArrayList<E>();
- for (E element : c) {
- if (test != null) {
- Object result = test.call(element);
- if (result != null && result instanceof Boolean && (Boolean) result && !duplicates.contains(element)) {
- values.add(element);
- }
- } else if (!duplicates.contains(element)) {
- values.add(element);
- }
- }
- if (!values.isEmpty()) {
- fireMultiElementAddedEvent(values);
- fireSizeChangedEvent(oldSize, size());
- }
- }
-
- return success;
- }
-
- public boolean retainAll(Collection<?> c) {
- if (c == null) {
- return false;
- }
-
- List values = new ArrayList();
- // GROOVY-7822 use Set for O(1) performance for contains
- if (!(c instanceof Set)) {
- c = new HashSet<Object>(c);
- }
- for (Object element : delegate) {
- if (!c.contains(element)) {
- values.add(element);
- }
- }
-
- int oldSize = size();
- boolean success = delegate.retainAll(c);
- if (success && !values.isEmpty()) {
- fireMultiElementRemovedEvent(values);
- fireSizeChangedEvent(oldSize, size());
- }
-
- return success;
- }
-
- public boolean removeAll(Collection<?> c) {
- if (c == null) {
- return false;
- }
-
- List values = new ArrayList();
- for (Object element : c) {
- if (delegate.contains(element)) {
- values.add(element);
- }
- }
-
- int oldSize = size();
- boolean success = delegate.removeAll(c);
- if (success && !values.isEmpty()) {
- fireMultiElementRemovedEvent(values);
- fireSizeChangedEvent(oldSize, size());
- }
-
- return success;
- }
-
- public void clear() {
- int oldSize = size();
- List<E> values = new ArrayList<E>();
- values.addAll(delegate);
- delegate.clear();
- if (!values.isEmpty()) {
- fireElementClearedEvent(values);
- }
- fireSizeChangedEvent(oldSize, size());
- }
-
- protected class ObservableIterator<E> implements Iterator<E> {
- private final Iterator<E> iterDelegate;
- private final Stack<E> stack = new Stack<E>();
-
- public ObservableIterator(Iterator<E> iterDelegate) {
- this.iterDelegate = iterDelegate;
- }
-
- public Iterator<E> getDelegate() {
- return iterDelegate;
- }
-
- public boolean hasNext() {
- return iterDelegate.hasNext();
- }
-
- public E next() {
- stack.push(iterDelegate.next());
- return stack.peek();
- }
-
- public void remove() {
- int oldSize = ObservableSet.this.size();
- iterDelegate.remove();
- fireElementRemovedEvent(stack.pop());
- fireSizeChangedEvent(oldSize, size());
- }
- }
-
- public enum ChangeType {
- ADDED, REMOVED, CLEARED, MULTI_ADD, MULTI_REMOVE, NONE;
-
- public static final Object oldValue = new Object();
- public static final Object newValue = new Object();
- }
-
- public abstract static class ElementEvent extends PropertyChangeEvent {
- private final ChangeType type;
-
- public ElementEvent(Object source, Object oldValue, Object newValue, ChangeType type) {
- super(source, ObservableSet.CONTENT_PROPERTY, oldValue, newValue);
- this.type = type;
- }
-
- public int getType() {
- return type.ordinal();
- }
-
- public ChangeType getChangeType() {
- return type;
- }
-
- public String getTypeAsString() {
- return type.name().toUpperCase();
- }
- }
-
- public static class ElementAddedEvent extends ElementEvent {
- public ElementAddedEvent(Object source, Object newValue) {
- super(source, null, newValue, ChangeType.ADDED);
- }
- }
-
- public static class ElementRemovedEvent extends ElementEvent {
- public ElementRemovedEvent(Object source, Object value) {
- super(source, value, null, ChangeType.REMOVED);
- }
- }
-
- public static class ElementClearedEvent extends ElementEvent {
- private final List values = new ArrayList();
-
- public ElementClearedEvent(Object source, List values) {
- super(source, ChangeType.oldValue, ChangeType.newValue, ChangeType.CLEARED);
- if (values != null) {
- this.values.addAll(values);
- }
- }
-
- public List getValues() {
- return Collections.unmodifiableList(values);
- }
- }
-
- public static class MultiElementAddedEvent extends ElementEvent {
- private final List values = new ArrayList();
-
- public MultiElementAddedEvent(Object source, List values) {
- super(source, ChangeType.oldValue, ChangeType.newValue, ChangeType.MULTI_ADD);
- if (values != null) {
- this.values.addAll(values);
- }
- }
-
- public List getValues() {
- return Collections.unmodifiableList(values);
- }
- }
-
- public static class MultiElementRemovedEvent extends ElementEvent {
- private final List values = new ArrayList();
-
- public MultiElementRemovedEvent(Object source, List values) {
- super(source, ChangeType.oldValue, ChangeType.newValue, ChangeType.MULTI_REMOVE);
- if (values != null) {
- this.values.addAll(values);
- }
- }
-
- public List getValues() {
- return Collections.unmodifiableList(values);
- }
- }
-}