You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2009/10/04 21:38:02 UTC
svn commit: r821590 - in
/commons/proper/configuration/branches/configuration2_experimental/src:
main/java/org/apache/commons/configuration2/base/Capabilities.java
test/java/org/apache/commons/configuration2/base/TestCapabilities.java
Author: oheger
Date: Sun Oct 4 19:38:02 2009
New Revision: 821590
URL: http://svn.apache.org/viewvc?rev=821590&view=rev
Log:
Added new Capabilities class for managing the capabilities supported by a ConfigurationSource.
Added:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java (with props)
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java (with props)
Added: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java?rev=821590&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java Sun Oct 4 19:38:02 2009
@@ -0,0 +1,155 @@
+/*
+ * 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 org.apache.commons.configuration2.base;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * <p>
+ * A class for managing <em>capabilities</em>.
+ * </p>
+ * <p>
+ * This class is intended to support the implementation of the {@code
+ * getCapability()} method defined by the {@link ConfigurationSource} interface.
+ * It maintains the capabilities provided by a concrete configuration source
+ * implementation.
+ * </p>
+ * <p>
+ * An instance is initialized with a reference to an owner and a collection of
+ * {@link Capability} objects. The passed in {@link Capability} objects are
+ * stored directly. From the owner object a list of all implemented interfaces
+ * is obtained, and corresponding {@link Capability} objects are created for
+ * them. The {@code getCapability()} method queries the internal list of
+ * {@link Capability} objects created this way and returns the implementation
+ * objects if a matching class is found. This is exactly what is needed for the
+ * implementation of the {@link ConfigurationSource#getCapability(Class)}
+ * method.
+ * </p>
+ * <p>
+ * Implementation note: This class is immutable.
+ * </p>
+ *
+ * @author Commons Configuration team
+ * @version $Id$
+ */
+public class Capabilities
+{
+ /** The capabilities managed by this instance. */
+ private final Collection<Capability> capabilities;
+
+ /**
+ * Creates a new instance of {@code Capabilities} and initializes it with an
+ * owner and a collection of {@code Capability} objects.
+ *
+ * @param owner the owner object (can be <b>null</b>)
+ * @param caps the collection with {@code Capability} objects (can be
+ * <b>null</b>)
+ * @throws IllegalArgumentException if one of the {@code Capability} objects
+ * in the collection is <b>null</b>
+ */
+ public Capabilities(Object owner, Collection<? extends Capability> caps)
+ {
+ if (caps == null)
+ {
+ capabilities = new ArrayList<Capability>();
+ }
+ else
+ {
+ capabilities = new ArrayList<Capability>(caps);
+ for (Capability c : capabilities)
+ {
+ if (c == null)
+ {
+ throw new IllegalArgumentException(
+ "Capability must not be null!");
+ }
+ }
+ }
+
+ if (owner != null)
+ {
+ extractOwnerCapabilities(capabilities, owner);
+ }
+ }
+
+ /**
+ * Returns the capability implementation object for the specified capability
+ * (interface) class. This method queries all {@link Capability} objects
+ * stored internally whether they match the specified class. If a match is
+ * found, the corresponding implementation object is returned.
+ * {@link Capability} objects directly passed to the constructor are queried
+ * first (in the order they are provided), then the capabilities obtained
+ * from the interfaces of the owner object are searched. Therefore it is
+ * possible to override interfaces implemented by the owner object by
+ * providing corresponding {@link Capability} instances.
+ *
+ * @param <T> the type of the capability
+ * @param capabilityClass the capability class
+ * @return the object implementing this capability or <b>null</b> if this
+ * capability is not supported
+ */
+ public <T> T getCapability(Class<T> capabilityClass)
+ {
+ for (Capability cap : capabilities)
+ {
+ if (cap.matches(capabilityClass))
+ {
+ return capabilityClass.cast(cap.getCapabilityObject());
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a string representation of this object. This string contains the
+ * string representations of all {@code Capability} objects managed by this
+ * instance.
+ *
+ * @return a string for this object
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder buf = new StringBuilder();
+ buf.append("Capabilities [ capabilities = ");
+ buf.append(capabilities);
+ buf.append(" ]");
+ return buf.toString();
+ }
+
+ /**
+ * Creates {@code Capability} objects for the interfaces implemented by the
+ * owner object. This method is called by the constructor if an owner object
+ * is provided. Note: It is safe to use raw types here because it is ensured
+ * that the owner object actually can be casted to the interfaces it
+ * implements.
+ *
+ * @param caps the list with the capabilities
+ * @param owner the owner object
+ */
+ @SuppressWarnings("unchecked")
+ private static void extractOwnerCapabilities(Collection<Capability> caps,
+ Object owner)
+ {
+ for (Class capCls : owner.getClass().getInterfaces())
+ {
+ caps.add(new Capability(capCls, owner));
+ }
+ }
+}
Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/Capabilities.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java?rev=821590&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java Sun Oct 4 19:38:02 2009
@@ -0,0 +1,159 @@
+/*
+ * 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 org.apache.commons.configuration2.base;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+/**
+ * Test class for {@code Capabilities}.
+ *
+ * @author Commons Configuration team
+ * @version $Id$
+ */
+public class TestCapabilities extends TestCase
+{
+ /**
+ * Tries to create an instance with a null capability in the collection.
+ * This should cause an exception.
+ */
+ public void testInitNullCapability()
+ {
+ Collection<Capability> caps = new ArrayList<Capability>();
+ caps.add(new Capability(Runnable.class, EasyMock
+ .createNiceMock(Runnable.class)));
+ caps.add(null);
+ try
+ {
+ new Capabilities(this, caps);
+ fail("Null capability not detected!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tries to create an instance without a data and capabilities. This should
+ * be possible, however, it is not very useful.
+ */
+ public void testInitNoData()
+ {
+ Capabilities caps = new Capabilities(null, null);
+ assertNull("Got a capability", caps.getCapability(Object.class));
+ }
+
+ /**
+ * Tests whether a defensive copy of the capabilities collection is created.
+ */
+ public void testInitCollectionModify()
+ {
+ Runnable r = EasyMock.createMock(Runnable.class);
+ ConfigurationSource src = EasyMock
+ .createMock(ConfigurationSource.class);
+ EasyMock.replay(r, src);
+ Collection<Capability> col = new ArrayList<Capability>();
+ col.add(new Capability(Runnable.class, r));
+ col.add(new Capability(ConfigurationSource.class, src));
+ Capabilities caps = new Capabilities(null, col);
+ col.clear();
+ assertEquals("Capability not found (1)", r, caps
+ .getCapability(Runnable.class));
+ assertEquals("Capability not found (2)", src, caps
+ .getCapability(ConfigurationSource.class));
+ EasyMock.verify(r, src);
+ }
+
+ /**
+ * Tests whether the instances implemented by the owner can be queried.
+ */
+ public void testGetCapabilityFromOwner()
+ {
+ MapConfigurationSource owner = new MapConfigurationSource();
+ Capabilities caps = new Capabilities(owner, null);
+ assertSame("Wrong source", owner, caps
+ .getCapability(ConfigurationSource.class));
+ assertSame("Wrong flat source", owner, caps
+ .getCapability(FlatConfigurationSource.class));
+ }
+
+ /**
+ * Tests whether capabilities from the list can be obtained.
+ */
+ public void testGetCapabilityFromList()
+ {
+ Runnable r = EasyMock.createMock(Runnable.class);
+ EasyMock.replay(r);
+ Collection<Capability> col = new ArrayList<Capability>();
+ col.add(new Capability(Runnable.class, r));
+ Capabilities caps = new Capabilities(null, col);
+ assertEquals("Wrong capability", r, caps.getCapability(Runnable.class));
+ EasyMock.verify(r);
+ }
+
+ /**
+ * Tests whether capabilities in the list overwrite interfaces implemented
+ * by the owner.
+ */
+ public void testGetCapabilityOverwrite()
+ {
+ ConfigurationSource src = EasyMock
+ .createMock(ConfigurationSource.class);
+ EasyMock.replay(src);
+ Capability c = new Capability(ConfigurationSource.class, src);
+ MapConfigurationSource mapSrc = new MapConfigurationSource();
+ Capabilities caps = new Capabilities(mapSrc, Collections.singleton(c));
+ assertEquals("Wrong source capability", src, caps
+ .getCapability(ConfigurationSource.class));
+ assertEquals("Wrong flat source capability", mapSrc, caps
+ .getCapability(FlatConfigurationSource.class));
+ EasyMock.verify(src);
+ }
+
+ /**
+ * Tries to query a null capability.
+ */
+ public void testGetCapabilityNull()
+ {
+ Capabilities caps = new Capabilities(new MapConfigurationSource(), null);
+ assertNull("Got null capability", caps.getCapability(null));
+ }
+
+ /**
+ * Tests the string representation.
+ */
+ public void testToString()
+ {
+ Runnable r = EasyMock.createMock(Runnable.class);
+ EasyMock.replay(r);
+ Capability c = new Capability(Runnable.class, r);
+ MapConfigurationSource owner = new MapConfigurationSource();
+ Capabilities caps = new Capabilities(owner, Collections.singleton(c));
+ String s = caps.toString();
+ assertTrue("Runnable capability not found: " + s, s.indexOf(c
+ .toString()) > 0);
+ assertTrue("Flat source capability not found: " + s, s
+ .indexOf(new Capability(FlatConfigurationSource.class, owner)
+ .toString()) > 0);
+ }
+}
Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestCapabilities.java
------------------------------------------------------------------------------
svn:mime-type = text/plain