geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jboy...@apache.org
Subject svn commit: r154723 - in geronimo/trunk/modules/kernel/src: java/org/apache/geronimo/gbean/GBeanName.java test/org/apache/geronimo/gbean/GBeanNameTest.java
Date Mon, 21 Feb 2005 21:19:09 GMT
Author: jboynes
Date: Mon Feb 21 13:19:07 2005
New Revision: 154723

URL: http://svn.apache.org/viewcvs?view=rev&rev=154723
Log:
initial impl of GBeanName

Added:
    geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/GBeanName.java
    geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/gbean/GBeanNameTest.java

Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/GBeanName.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/GBeanName.java?view=auto&rev=154723
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/GBeanName.java (added)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/GBeanName.java Mon Feb
21 13:19:07 2005
@@ -0,0 +1,184 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  Licensed 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.geronimo.gbean;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+
+/**
+ * Class that represents the name for a GBean.
+ * A name is comprised of a domain combined with one or more properties.
+ * The domain is a fixed base name, properties qualify that as necessary.
+ * Two names are equal if they have the same name and the same properties.
+ * The String representation of a name can be written as domain:key1=value1,key2=value2,...
+ * Values are case sensitive, spaces are significant and there is no escaping mechanism;
+ * this is intended to be fast rather than allow lax syntax.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class GBeanName implements Serializable {
+    private static final long serialVersionUID = 8571821054715922993L;
+
+    /**
+     * Original name preserved; used for toString and Serialized form
+     */
+    private final String name;
+    private final transient String domain;
+    private final transient Properties props;
+    private final transient int hashCode;
+
+    /**
+     * Construct a GBeanName by combining a domain with explicit properties.
+     * The string representation of this name is generated by combining the properties in
sorted order.
+     *
+     * @param domain the domain
+     * @param props the properties used to qualify this name
+     */
+    public GBeanName(String domain, Properties props) {
+        if (domain == null) {
+            throw new IllegalArgumentException("domain is null");
+        } else if (props == null) {
+            throw new IllegalArgumentException("props is null");
+        } else if (props.isEmpty()) {
+            throw new IllegalArgumentException("props is empty");
+        }
+        this.domain = domain;
+        this.props = new Properties(props);
+        this.name = sortName(domain, props);
+        this.hashCode = domain.hashCode() + 37 * props.hashCode();
+    }
+
+    /**
+     * Construct a GBeanName by parsing a string.
+     * @param name the name to parse
+     */
+    public GBeanName(String name) {
+        int idx = name.indexOf(':');
+        if (idx == -1) {
+            throw new IllegalArgumentException("Missing ':' for domain: " + name);
+        }
+        this.name = name;
+        this.domain = name.substring(0, idx);
+        this.props = parseName(name.substring(idx + 1));
+        this.hashCode = domain.hashCode() + 37 * props.hashCode();
+    }
+
+    private static Properties parseName(String name) {
+        if (name.endsWith(",")) {
+            throw new IllegalArgumentException("Missing last property pair");
+        }
+        Properties props = new Properties();
+        String[] pairs = name.split(",");
+        for (int i = 0; i < pairs.length; i++) {
+            String pair = pairs[i];
+            int idx = pair.indexOf('=');
+            if (idx == -1) {
+                throw new IllegalArgumentException("Invalid property pair: " + pair);
+            }
+            String key = pair.substring(0, idx);
+            String value = pair.substring(idx + 1);
+            if (props.put(key, value) != null) {
+                throw new IllegalArgumentException("Duplicate property: " + key);
+            }
+        }
+        return props;
+    }
+
+    private static String sortName(String domain, Map props) {
+        String[] names = (String[]) props.keySet().toArray(new String[props.size()]);
+        Arrays.sort(names);
+        StringBuffer buf = new StringBuffer(128);
+        buf.append(domain).append(':');
+        buf.append(names[0]).append('=').append(props.get(names[0]));
+        for (int i = 1; i < names.length; i++) {
+            String name = names[i];
+            buf.append(',').append(name).append('=').append(props.get(name));
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Determine if this name matches the supplied pattern.
+     * This performs a fast but simplistic pattern match which is true if:
+     * <ul>
+     * <li>The domains are equal</li>
+     * <li>If this instance has all the supplied properties with equal values</li>
+     * <ul>
+     * A null domain and a null or empty properties object are considered wildcards
+     * and always match; in other words GBeanName.match(null, new Properties()) will
+     * always evaluate to true.
+     *
+     * @param domain the domain to match
+     * @param pattern the set properties to match
+     * @return true if this instance matches the pattern
+     */
+    public boolean matches(String domain, Properties pattern) {
+        if (domain != null) {
+            if (!this.domain.equals(domain)) {
+                return false;
+            }
+        }
+        if (pattern != null && !pattern.isEmpty()) {
+            for (Iterator i = pattern.entrySet().iterator(); i.hasNext();) {
+                Map.Entry entry = (Map.Entry) i.next();
+                String key = (String) entry.getKey();
+                String ourValue = (String) props.get(key);
+                if (ourValue == null || !ourValue.equals(entry.getValue())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Test for equality.
+     * This instance will be equal if the supplied object is a GBeanName with
+     * equal domain and properties.
+     * @param obj
+     * @return
+     */
+    public boolean equals(Object obj) {
+        if (obj == this) return true;
+        if (obj instanceof GBeanName == false) return false;
+        final GBeanName other = (GBeanName) obj;
+        return this.domain.equals(other.domain) && this.props.equals(other.props);
+    }
+
+    public int hashCode() {
+        return hashCode;
+    }
+
+    /**
+     * Return a human readable version of this GBeanName. If the instance was created
+     * by parsing a String, this will be the supplied value; it it was created by
+     * supplying properties, the name will contain properties in sorted order.
+     *
+     * @return a readable name
+     */
+    public String toString() {
+        return name;
+    }
+
+    private Object readResolve() {
+        return new GBeanName(name);
+    }
+}
\ No newline at end of file

Added: geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/gbean/GBeanNameTest.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/gbean/GBeanNameTest.java?view=auto&rev=154723
==============================================================================
--- geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/gbean/GBeanNameTest.java (added)
+++ geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/gbean/GBeanNameTest.java Mon
Feb 21 13:19:07 2005
@@ -0,0 +1,157 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  Licensed 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.geronimo.gbean;
+
+import java.util.Properties;
+import java.util.HashSet;
+import java.util.Set;
+import java.rmi.MarshalledObject;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class GBeanNameTest extends TestCase {
+    private Properties props;
+
+    public void testPropertyConstruction() {
+        String domain = "testDomain";
+        props.put("prop1", "value1");
+        props.put("prop2", "value2");
+        GBeanName name = new GBeanName(domain, props);
+        assertEquals("testDomain:prop1=value1,prop2=value2", name.toString());
+    }
+
+    public void testNameConstruction() {
+        GBeanName name = new GBeanName("testDomain:prop1=value1,prop2=value2");
+        assertEquals("testDomain:prop1=value1,prop2=value2", name.toString());
+
+        name = new GBeanName("testDomain:prop2=value2,prop1=value1");
+        assertEquals("testDomain:prop2=value2,prop1=value1", name.toString());
+    }
+
+    public void testMatches() {
+        GBeanName name = new GBeanName("testDomain:prop1=value1,prop2=value2");
+        assertTrue(name.matches(null, null));
+        assertTrue(name.matches(null, props));
+        assertTrue(name.matches("testDomain", null));
+        assertTrue(name.matches("testDomain", props));
+
+        assertFalse(name.matches("test", null));
+        assertFalse(name.matches("test", props));
+
+        props.setProperty("prop1", "value2");
+        assertFalse(name.matches("testDomain", props));
+        props.setProperty("prop1", "value1");
+        assertTrue(name.matches("testDomain", props));
+        props.setProperty("prop2", "value2");
+        assertTrue(name.matches("testDomain", props));
+        props.setProperty("prop3", "value3");
+        assertFalse(name.matches("testDomain", props));
+    }
+
+    public void testInvalidNames() {
+        try {
+            new GBeanName(null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+        try {
+            new GBeanName("");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("foo=bar");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:  ");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:foo");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:x=x,foo");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:x=x,").toString();
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:x=x, ").toString();
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:,x=x");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:x=x,,y=y");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            new GBeanName("x:x=x,x=x");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testEquals() {
+        GBeanName name = new GBeanName("testDomain:prop1=value1,prop2=value2");
+        assertEquals(name, name);
+        assertEquals(new GBeanName("testDomain:prop2=value2,prop1=value1"), name);
+        assertFalse(name.equals(new GBeanName("foo:prop1=value1,prop2=value2")));
+        assertFalse(name.equals(new GBeanName("testDomain:prop1=value1")));
+        assertFalse(name.equals(new GBeanName("testDomain:prop2=value2")));
+        assertFalse(name.equals(new GBeanName("testDomain:prop2=value2")));
+        assertFalse(name.equals(new GBeanName("testDomain:prop1=value1,prop2=value2,prop3=value3")));
+
+        Set set = new HashSet();
+        set.add(name);
+        set.add(name);
+        assertEquals(1, set.size());
+    }
+
+    public void testSerialization() throws Exception {
+        GBeanName name = new GBeanName("testDomain:prop1=value1,prop2=value2");
+        MarshalledObject o = new MarshalledObject(name);
+        GBeanName name2 = (GBeanName) o.get();
+        assertEquals(name, name2);
+    }
+
+    protected void setUp() throws Exception {
+        props = new Properties();
+    }
+}



Mime
View raw message