Author: julien(a)jboss.com
Date: 2008-04-16 18:32:16 -0400 (Wed, 16 Apr 2008)
New Revision: 10612
Added:
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/MapAdapters.java
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/MapAdaptersTestCase.java
Modified:
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/AbstractTypedMap.java
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapEntrySetTestCase.java
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapTestCase.java
Log:
- fixed bugs and added test case in typed map
- added a MapAdapters that is provides various adapters (for now a generic Map<T,
T[]> to Map<T, T> and Map<String, String[]> to Map<String> which
makes it easier to read parameter maps.
Modified:
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/AbstractTypedMap.java
===================================================================
---
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/AbstractTypedMap.java 2008-04-16
21:18:10 UTC (rev 10611)
+++
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/AbstractTypedMap.java 2008-04-16
22:32:16 UTC (rev 10612)
@@ -64,6 +64,29 @@
public abstract static class Converter<E, I>
{
+ private static final Converter identity = new Converter()
+ {
+ protected Object getInternal(Object external) throws IllegalArgumentException,
ClassCastException
+ {
+ return external;
+ }
+
+ protected Object getExternal(Object internal) throws IllegalArgumentException,
ClassCastException
+ {
+ return internal;
+ }
+
+ protected boolean equals(Object left, Object right)
+ {
+ return left.equals(false);
+ }
+ };
+
+ public static <T> Converter<T, T> identityConverter()
+ {
+ return (Converter<T,T>)identity;
+ }
+
private final Transformer<I, E> keyUnwrapper = new Transformer<I, E>()
{
protected I transform(E e)
@@ -211,20 +234,17 @@
public final EV put(EK ek, EV ev)
{
+ Map<IK, IV> map = getDelegate();
IK ik = getKeyConverter().keyUnwrapper.transform(ek);
- IV iv = getValueConverter().valueUnwrapper.transform(ev);
- Map<IK, IV> map = getDelegate();
+ boolean contains = map.containsKey(ik);
//
+ IV iv = getValueConverter().valueUnwrapper.transform(ev);
iv = map.put(ik, iv);
// Do we have a result ?
- if (iv == null)
+ if (contains)
{
- ev = null;
- }
- else
- {
boolean rollback = true;
try
{
@@ -239,6 +259,10 @@
}
}
}
+ else
+ {
+ ev = null;
+ }
//
return ev;
@@ -248,9 +272,10 @@
{
EK ek = (EK)key;
IK ik = getKeyConverter().keyUnwrapper.transform(ek);
- IV iv = getDelegate().get(ik);
+ Map<IK, IV> map = getDelegate();
+ IV iv = map.get(ik);
EV ev = null;
- if (iv != null)
+ if (iv != null || map.containsKey(ik))
{
ev = getValueConverter().valueWrapper.transform(iv);
}
@@ -262,15 +287,15 @@
EK ek = (EK)key;
IK ik = getKeyConverter().keyUnwrapper.transform(ek);
Map<IK, IV> map = getDelegate();
- IV iv = map.remove(ik);
- EV ev = null;
- if (iv != null)
+ if (getDelegate().containsKey(ik))
{
+ IV iv = map.remove(ik);
boolean rollback = true;
try
{
- ev = getValueConverter().valueWrapper.transform(iv);
+ EV ev = getValueConverter().valueWrapper.transform(iv);
rollback = false;
+ return ev;
}
finally
{
@@ -280,7 +305,10 @@
}
}
}
- return ev;
+ else
+ {
+ return null;
+ }
}
public final boolean containsValue(Object value)
Added:
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/MapAdapters.java
===================================================================
---
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/MapAdapters.java
(rev 0)
+++
modules/common/trunk/common/src/main/java/org/jboss/portal/common/util/MapAdapters.java 2008-04-16
22:32:16 UTC (rev 10612)
@@ -0,0 +1,128 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2008, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.common.util;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * A collection of various map adapters.
+ *
+ * @author <a href="mailto:julien@jboss-portal.org">Julien
Viet</a>
+ * @version $Revision: 630 $
+ */
+public class MapAdapters
+{
+
+ /** . */
+ private final static ArrayElementConverter<String> stringArrayElementConverter =
new ArrayElementConverter<String>(String.class);
+
+ /** . */
+ private final static AbstractTypedMap.Converter<String, String> stringConverter
= AbstractTypedMap.Converter.identityConverter();
+
+ public static <K,V> Map<K,V> adapt(Map<K, V[]> adapted, Class<?
extends V> type)
+ {
+ if (adapted == null)
+ {
+ throw new IllegalArgumentException("Cannot adapt a null map");
+ }
+ ArrayElementConverter<V> valueConverter = new
ArrayElementConverter<V>(type);
+ AbstractTypedMap.Converter<K, K> keyConverter =
AbstractTypedMap.Converter.identityConverter();
+ return new TypedMap<K, V, K, V[]>(adapted, keyConverter, valueConverter);
+ }
+
+ /**
+ * <p>Adapt a <code>Map<String, String[]></code> map as a
<code>Map<String, String></code> map. The adapted map
+ * must not contain null string array or zero lenght string array, if the map contains
such values then the
+ * map state is considered as not valid and {@link IllegalStateException} can be
thrown when the adapted map</p>
+ * is used.
+ *
+ * <p>The adapted map is writable but does not accept null values for write
operations. On a put operation
+ * the adapted map will receive a put operation with a string array of length one
containing the provided value.</p>
+ *
+ * @param adapted the adapted map
+ * @return the adapter
+ */
+ public static Map<String, String> adapt(Map<String, String[]> adapted)
+ {
+ if (adapted == null)
+ {
+ throw new IllegalArgumentException("Cannot adapt a null map");
+ }
+ return new TypedMap<String, String, String, String[]>(adapted,
stringConverter, stringArrayElementConverter);
+ }
+
+ private static class ArrayElementConverter<T> extends
AbstractTypedMap.Converter<T, T[]>
+ {
+
+ /** . */
+ private final Class<? extends T> type;
+
+ private ArrayElementConverter(Class<? extends T> type)
+ {
+ if (type == null)
+ {
+ throw new IllegalArgumentException("No null type accepted");
+ }
+ this.type = type;
+ }
+
+ protected T[] getInternal(T external) throws IllegalArgumentException,
ClassCastException
+ {
+ if (external == null)
+ {
+ throw new NullPointerException();
+ }
+
+ //
+ T[] array = (T[])Array.newInstance(type, 1);
+ array[0] = external;
+
+ //
+ return array;
+ }
+
+ protected T getExternal(T[] internal) throws IllegalArgumentException,
ClassCastException
+ {
+ if (internal == null)
+ {
+ throw new IllegalStateException();
+ }
+
+ //
+ if (internal.length == 0)
+ {
+ throw new IllegalStateException();
+ }
+
+ //
+ return internal[0];
+ }
+
+ protected boolean equals(T[] left, T[] right)
+ {
+ return Arrays.equals(left, right);
+ }
+ }
+}
Added:
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/MapAdaptersTestCase.java
===================================================================
---
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/MapAdaptersTestCase.java
(rev 0)
+++
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/MapAdaptersTestCase.java 2008-04-16
22:32:16 UTC (rev 10612)
@@ -0,0 +1,123 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2008, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.test.common.util;
+
+import junit.framework.TestCase;
+import org.jboss.portal.common.util.MapAdapters;
+import org.jboss.portal.common.util.MapBuilder;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @author <a href="mailto:julien@jboss-portal.org">Julien
Viet</a>
+ * @version $Revision: 630 $
+ */
+public class MapAdaptersTestCase extends TestCase
+{
+
+ /** . */
+ Map<String, String[]> adapted;
+
+ /** . */
+ Map<String, String> adapter;
+
+ protected void setUp() throws Exception
+ {
+ adapted = new HashMap<String, String[]>();
+ adapter = MapAdapters.adapt(adapted);
+ }
+
+ public void testGet()
+ {
+ adapted.put("daa", null);
+ adapted.put("foo", new String[]{});
+ adapted.put("bar", new String[]{"bar_1"});
+ adapted.put("juu", new String[]{"juu_1","juu_2"});
+
+ //
+ try
+ {
+ adapter.get("foo");
+ fail();
+ }
+ catch (IllegalStateException ignore)
+ {
+ }
+ try
+ {
+ adapter.get("daa");
+ fail();
+ }
+ catch (IllegalStateException ignore)
+ {
+ }
+
+ //
+ assertEquals("bar_1", adapter.get("bar"));
+ assertEquals("juu_1", adapter.get("juu"));
+ }
+
+ public void testPut1()
+ {
+ try
+ {
+ adapter.put("foo", null);
+ fail();
+ }
+ catch (NullPointerException e)
+ {
+ }
+ }
+
+ public void testPut2()
+ {
+ adapted.put("foo", new String[]{"bar_1","bar_2"});
+ assertEquals("bar_1", adapter.put("foo", "foo_1"));
+ assertEquals(1, adapted.size());
+ String[] value = adapted.get("foo");
+ assertNotNull(value);
+ assertEquals(1, value.length);
+ assertEquals("foo_1", value[0]);
+ }
+
+ public void testPut3()
+ {
+ adapted.put("foo", new String[]{"bar_1","bar_2"});
+ try
+ {
+ adapter.put("foo", null);
+ fail();
+ }
+ catch (NullPointerException e)
+ {
+ assertEquals(1, adapted.size());
+ String[] value = adapted.get("foo");
+ assertNotNull(value);
+ assertEquals(2, value.length);
+ assertEquals("bar_1", value[0]);
+ assertEquals("bar_2", value[1]);
+ }
+ }
+
+}
Modified:
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapEntrySetTestCase.java
===================================================================
---
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapEntrySetTestCase.java 2008-04-16
21:18:10 UTC (rev 10611)
+++
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapEntrySetTestCase.java 2008-04-16
22:32:16 UTC (rev 10612)
@@ -30,6 +30,7 @@
import java.util.Iterator;
import org.jboss.portal.common.util.Tools;
+import org.jboss.portal.common.util.MapBuilder;
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
@@ -441,6 +442,37 @@
}
}
+ public void testGetValueWithNullValue()
+ {
+ delegate.put(0L, null);
+ delegate.remove(1L);
+ Map.Entry<String, String> entry = entries.iterator().next();
+ try
+ {
+ entry.getValue();
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ }
+
+ public void testSetValueWithPreviousNullValue()
+ {
+ delegate.put(0L, null);
+ delegate.remove(1L);
+ Map.Entry<String, String> entry = entries.iterator().next();
+ try
+ {
+ entry.setValue("1");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals(MapBuilder.hashMap(0L, (Integer)null).get(), delegate);
+ }
+ }
+
//
public void testSize()
Modified:
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapTestCase.java
===================================================================
---
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapTestCase.java 2008-04-16
21:18:10 UTC (rev 10611)
+++
modules/common/trunk/common/src/test/java/org/jboss/portal/test/common/util/typedmap/TypedMapTestCase.java 2008-04-16
22:32:16 UTC (rev 10612)
@@ -561,7 +561,47 @@
}
//
+ public void testGetInternalNullValue()
+ {
+ delegate.put(0l, null);
+ try
+ {
+ map.get("zero");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ }
+ public void testRemoveInternalNullValue()
+ {
+ delegate.put(0l, null);
+ try
+ {
+ map.remove("zero");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals(MapBuilder.hashMap(0L, null).get(), delegate);
+ }
+ }
+
+ public void testPutOldInternalNullValue()
+ {
+ delegate.put(0l, null);
+ try
+ {
+ map.put("zero", "0");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals(MapBuilder.hashMap(0L, null).get(), delegate);
+ }
+ }
+
// blih
// public void testGetInternalValueConvertedToNull()
// {