Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java (original) +++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java Mon Mar 24 20:37:56 2008 @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import org.apache.openjpa.lib.util.EventManager; @@ -39,7 +40,7 @@ public abstract class AbstractConcurrentEventManager implements EventManager, Serializable { - private static Exception[] EMPTY_EXCEPTIONS = new Exception[0]; + private static final Exception[] EMPTY_EXCEPTIONS = new Exception[0]; protected final Collection _listeners; private boolean _failFast = false;
Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ConcurrentReferenceHashSet.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ConcurrentReferenceHashSet.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ConcurrentReferenceHashSet.java (original) +++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ConcurrentReferenceHashSet.java Mon Mar 24 20:37:56 2008 @@ -22,11 +22,15 @@ import java.util.Collection; import java.util.Iterator; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.collections.set.MapBackedSet; /** - * A concurrent set whose values may be stored as weak or soft references. + * A concurrent set whose values may be stored as weak or soft references. If + * the constructor is invoked with <code>refType</code> set to [EMAIL PROTECTED] #HARD}, + * this uses a JDK1.5 [EMAIL PROTECTED] ConcurrentHashMap} under the covers. Otherwise, + * it uses a [EMAIL PROTECTED] ConcurrentReferenceHashMap}. * * @author Abe White * @nojavadoc Added: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java?rev=640685&view=auto ============================================================================== --- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java (added) +++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java Mon Mar 24 20:37:56 2008 @@ -0,0 +1,241 @@ +/* + * 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.openjpa.lib.util.concurrent; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; +import java.util.Enumeration; +import java.util.Set; +import java.util.Collection; +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.AbstractCollection; + +/** + * A subclass of [EMAIL PROTECTED] ConcurrentHashMap} that allows null keys and values. + * In exchange, it weakens the contract of [EMAIL PROTECTED] #putIfAbsent} and the other + * concurrent methods added in [EMAIL PROTECTED] #ConcurrentHashMap}. + * + * @since 1.1.0 + */ +public class NullSafeConcurrentHashMap extends ConcurrentHashMap { + + private enum Null { + MARKER + } + + public NullSafeConcurrentHashMap(int size, float load, + int concurrencyLevel) { + super(size, load, concurrencyLevel); + } + + public NullSafeConcurrentHashMap() { + } + + /** + * Returns internal representation for object. + */ + private static Object maskNull(Object o) { + return (o == null ? Null.MARKER : o); + } + + /** + * Returns object represented by specified internal representation. + */ + private static Object unmaskNull(Object o) { + return (o == Null.MARKER ? null : o); + } + + @Override + public Object remove(Object key) { + return unmaskNull(super.remove(maskNull(key))); + } + + @Override + public boolean remove(Object key, Object value) { + return super.remove(maskNull(key), maskNull(value)); + } + + @Override + public boolean replace(Object key, Object oldValue, Object newValue) { + return super.replace(maskNull(key), maskNull(oldValue), + maskNull(newValue)); + } + + @Override + public Object replace(Object key, Object value) { + return unmaskNull(super.replace(maskNull(key), maskNull(value))); + } + + @Override + public Object putIfAbsent(Object key, Object value) { + return unmaskNull(super.putIfAbsent(maskNull(key), maskNull(value))); + } + + @Override + public Object put(Object key, Object value) { + return unmaskNull(super.put(maskNull(key), maskNull(value))); + } + + @Override + public Object get(Object key) { + return unmaskNull(super.get(maskNull(key))); + } + + @Override + public boolean containsKey(Object key) { + return super.containsKey(maskNull(key)); + } + + @Override + public boolean containsValue(Object value) { + return super.containsValue(maskNull(value)); + } + + @Override + public boolean contains(Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration elements() { + throw new UnsupportedOperationException(); + } + + @Override + public Set entrySet() { + return new TranslatingSet(super.entrySet()) { + protected Object unmask(Object internal) { + final Entry e = (Entry) internal; + return new Entry() { + + public Object getKey() { + return unmaskNull(e.getKey()); + } + + public Object getValue() { + return unmaskNull(e.getValue()); + } + + public Object setValue(Object value) { + return unmaskNull(e.setValue(maskNull(value))); + } + + @Override + public int hashCode() { + return e.hashCode(); + } + }; + } + }; + } + + @Override + public Enumeration keys() { + throw new UnsupportedOperationException(); + } + + @Override + public Set keySet() { + return new TranslatingSet(super.keySet()) { + protected Object unmask(Object internal) { + return unmaskNull(internal); + } + }; + } + + @Override + public void putAll(Map t) { + super.putAll(t); + } + + @Override + public Collection values() { + return new TranslatingCollection(super.values()) { + + protected Object unmask(Object internal) { + return unmaskNull(internal); + } + }; + } + + private abstract class TranslatingSet extends AbstractSet { + + private Set backingSet; + + private TranslatingSet(Set backing) { + this.backingSet = backing; + } + + protected abstract Object unmask(Object internal); + + public Iterator iterator() { + final Iterator iterator = backingSet.iterator(); + return new Iterator() { + public boolean hasNext() { + return iterator.hasNext(); + } + + public Object next() { + return unmask(iterator.next()); + } + + public void remove() { + iterator.remove(); + } + }; + } + + public int size() { + return backingSet.size(); + } + } + + private abstract class TranslatingCollection extends AbstractCollection { + + private Collection backingCollection; + + private TranslatingCollection(Collection backing) { + this.backingCollection = backing; + } + + protected abstract Object unmask(Object internal); + + public Iterator iterator() { + final Iterator iterator = backingCollection.iterator(); + return new Iterator() { + public boolean hasNext() { + return iterator.hasNext(); + } + + public Object next() { + return unmask(iterator.next()); + } + + public void remove() { + iterator.remove(); + } + }; + } + + public int size() { + return backingCollection.size(); + } + } +} Added: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java?rev=640685&view=auto ============================================================================== --- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java (added) +++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java Mon Mar 24 20:37:56 2008 @@ -0,0 +1,152 @@ +/* + * 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.openjpa.lib.util.concurrent; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; +import java.util.Iterator; +import java.util.Set; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; + +import org.apache.openjpa.lib.util.SizedMap; + +/** + * An implementation of [EMAIL PROTECTED] SizedMap} that uses JDK1.5 concurrency primitives + * + * @since 1.1.0 + */ +public class SizedConcurrentHashMap + extends NullSafeConcurrentHashMap + implements SizedMap, ConcurrentMap, Serializable { + + private int maxSize; + + /** + * @param size the maximum size of this map. If additional elements are + * put into the map, overflow will be removed via calls to + * [EMAIL PROTECTED] #overflowRemoved}. + * @param load the load factor for the underlying map + * @param concurrencyLevel the concurrency level for the underlying map + * + * @see ConcurrentHashMap + */ + public SizedConcurrentHashMap(int size, float load, int concurrencyLevel) { + super(size, load, concurrencyLevel); + setMaxSize(size); + } + + @Override + public Object putIfAbsent(Object key, Object value) { + Object o = super.putIfAbsent(key, value); + if (maxSize != Integer.MAX_VALUE) + removeOverflow(); + return o; + } + + @Override + public Object put(Object key, Object value) { + Object o = super.put(key, value); + if (maxSize != Integer.MAX_VALUE) + removeOverflow(); + return o; + } + + public int getMaxSize() { + return maxSize; + } + + public void setMaxSize(int max) { + if (max < 0) + throw new IllegalArgumentException(String.valueOf(max)); + maxSize = max; + + removeOverflow(); + } + + protected void removeOverflow() { + while (size() > maxSize) { + Entry entry = removeRandom(); + // if removeRandom() returns null, break out of the loop. Of course, + // since we're not locking, the size might not actually be null + // when we do this. But this prevents weird race conditions from + // putting this thread into more loops. + if (entry == null) + break; + overflowRemoved(entry.getKey(), entry.getValue()); + } + } + + public boolean isFull() { + return size() >= maxSize; + } + + public Map.Entry removeRandom() { + // this isn't really random, but is concurrent. + while (true) { + if (size() == 0) + return null; + Set entries = entrySet(); + Entry e = (Entry) entries.iterator().next(); + final Object key = e.getKey(); + final Object val = e.getValue(); + if (remove(key) != null) + // create a new Entry instance because the ConcurrentHashMap + // implementation's one is "live" so does not behave as desired + // after removing the entry. + return new Entry() { + public Object getKey() { + return key; + } + + public Object getValue() { + return val; + } + + public Object setValue(Object value) { + throw new UnsupportedOperationException(); + } + }; + } + } + + public Iterator randomEntryIterator() { + // this isn't really random, but is concurrent. + return entrySet().iterator(); + } + + /** + * This implementation does nothing. + */ + public void overflowRemoved(Object key, Object value) { + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + out.writeInt(maxSize); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + maxSize = in.readInt(); + } +} Modified: openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java (original) +++ openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java Mon Mar 24 20:37:56 2008 @@ -855,8 +855,8 @@ Object result = in.readObject(); if (validateEquality) { - assertEquals(orig.hashCode(), result.hashCode()); assertEquals(orig, result); + assertEquals(orig.hashCode(), result.hashCode()); } return result; Modified: openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java (original) +++ openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java Mon Mar 24 20:37:56 2008 @@ -1,100 +1,100 @@ -/* - * 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.openjpa.lib.util; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.textui.TestRunner; -import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager; - -/** - * Tests the [EMAIL PROTECTED] AbstractConcurrentEventManager}. - * - * @author Abe White - */ -public class TestAbstractEventManager extends TestCase { - - private EventManager _em = new EventManager(); - - public TestAbstractEventManager(String test) { - super(test); - } - - public void testReentrantAdd() { - Listener l1 = new Listener(Listener.ADD); - Listener l2 = new Listener(Listener.NONE); - _em.addListener(l1); - _em.addListener(l2); - _em.fireEvent(new Object()); - assertTrue(l1.fired); - assertTrue(l2.fired); - assertEquals(3, _em.getListeners().size()); - } - - public void testReentrantRemove() { - Listener l1 = new Listener(Listener.REMOVE); - Listener l2 = new Listener(Listener.NONE); - _em.addListener(l1); - _em.addListener(l2); - _em.fireEvent(new Object()); - assertTrue(l1.fired); - assertTrue(l2.fired); - assertEquals(1, _em.getListeners().size()); - assertFalse(_em.getListeners().contains(l1)); - } - - public static Test suite() { - return new TestSuite(TestAbstractEventManager.class); - } - - public static void main(String[] args) { - TestRunner.run(suite()); - } - - private static class EventManager extends AbstractConcurrentEventManager { - - protected void fireEvent(Object event, Object listener) { - ((Listener) listener).fire(); - } - } - - private class Listener { - - public static final int NONE = 0; - public static final int ADD = 1; - public static final int REMOVE = 2; - - public boolean fired; - private final int _action; - - public Listener(int action) { - _action = action; - } - - public void fire() { - fired = true; - if (_action == ADD) - _em.addListener(new Listener(NONE)); - else if (_action == REMOVE) - assertTrue(_em.removeListener(this)); - } - } -} - +/* + * 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.openjpa.lib.util; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; +import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager; + +/** + * Tests the [EMAIL PROTECTED] AbstractConcurrentEventManager}. + * + * @author Abe White + */ +public class TestAbstractEventManager extends TestCase { + + private EventManager _em = new EventManager(); + + public TestAbstractEventManager(String test) { + super(test); + } + + public void testReentrantAdd() { + Listener l1 = new Listener(Listener.ADD); + Listener l2 = new Listener(Listener.NONE); + _em.addListener(l1); + _em.addListener(l2); + _em.fireEvent(new Object()); + assertTrue(l1.fired); + assertTrue(l2.fired); + assertEquals(3, _em.getListeners().size()); + } + + public void testReentrantRemove() { + Listener l1 = new Listener(Listener.REMOVE); + Listener l2 = new Listener(Listener.NONE); + _em.addListener(l1); + _em.addListener(l2); + _em.fireEvent(new Object()); + assertTrue(l1.fired); + assertTrue(l2.fired); + assertEquals(1, _em.getListeners().size()); + assertFalse(_em.getListeners().contains(l1)); + } + + public static Test suite() { + return new TestSuite(TestAbstractEventManager.class); + } + + public static void main(String[] args) { + TestRunner.run(suite()); + } + + private static class EventManager extends AbstractConcurrentEventManager { + + protected void fireEvent(Object event, Object listener) { + ((Listener) listener).fire(); + } + } + + private class Listener { + + public static final int NONE = 0; + public static final int ADD = 1; + public static final int REMOVE = 2; + + public boolean fired; + private final int _action; + + public Listener(int action) { + _action = action; + } + + public void fire() { + fired = true; + if (_action == ADD) + _em.addListener(new Listener(NONE)); + else if (_action == REMOVE) + assertTrue(_em.removeListener(this)); + } + } +} + Modified: openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestConcurrentMap.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestConcurrentMap.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestConcurrentMap.java (original) +++ openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestConcurrentMap.java Mon Mar 24 20:37:56 2008 @@ -25,31 +25,35 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.io.IOException; -import junit.framework.TestCase; import org.apache.openjpa.lib.util.ReferenceMap; +import org.apache.openjpa.lib.test.AbstractTestCase; /** * Tests the methods of [EMAIL PROTECTED] ConcurrentMap}. * * @author Abe White */ -public class TestConcurrentMap extends TestCase { +public class TestConcurrentMap extends AbstractTestCase { private static final int ENTRIES = 333; private static final int SLEEP = 3; private ConcurrentMap[] _maps = new ConcurrentMap[]{ - new ConcurrentHashMap(), + new SizedConcurrentHashMap(ENTRIES, .75f, 16), new ConcurrentReferenceHashMap(ReferenceMap.HARD, ReferenceMap.HARD), }; - public void setUp() { + public void setUp() throws Exception { + super.setUp(); for (int i = 0; i < ENTRIES; i++) { for (int j = 0; j < _maps.length; j++) { int key = j * ENTRIES + i; _maps[j].put(new Integer(key), "v" + key); } } + for (int i = 0; i < _maps.length; i++) + assertEquals(ENTRIES, _maps[i].size()); } public void testRemoveRandom() { @@ -118,9 +122,7 @@ } public void testRandomIterate() { - List l1 = iterationTest(true); - List l2 = iterationTest(true); - assertTrue(!l1.equals(l2)); + iterationTest(true); } private static class RemoveRandomRunnable implements Runnable { Added: openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java?rev=640685&view=auto ============================================================================== --- openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java (added) +++ openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java Mon Mar 24 20:37:56 2008 @@ -0,0 +1,126 @@ +/* + * 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.openjpa.lib.util.concurrent; + +import java.io.IOException; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Iterator; +import java.util.Set; +import java.util.Collection; +import java.util.Map; +import java.util.HashMap; +import java.util.Enumeration; +import java.util.Map.Entry; + +import org.apache.openjpa.lib.test.AbstractTestCase; + +public class TestNullSafeConcurrentHashMap extends AbstractTestCase { + + private Map newMap() { + return new NullSafeConcurrentHashMap(); +// return new HashMap(); + } + + public void testNullKeys() throws ClassNotFoundException, IOException { + Map m = newMap(); + helper(m, null, "value 0", "value 1", "value 2"); + } + + private void helper(Map m, Object key, Object value0, + Object value1, Object value2) + throws IOException, ClassNotFoundException { + + // initial put + m.put(key, value0); + + // get etc. + assertEquals(value0, m.get(key)); + assertTrue(m.containsKey(key)); + assertTrue(m.containsValue(value0)); + + // keySet + Set keys = m.keySet(); + assertTrue(keys.contains(key)); + assertEquals(1, keys.size()); + assertEquals(key, keys.iterator().next()); + + // entrySet + Set entries = m.entrySet(); + Entry e = (Entry) entries.iterator().next(); + assertEquals(key, e.getKey()); + assertEquals(value0, e.getValue()); + + // values + Collection values = m.values(); + assertEquals(1, values.size()); + assertEquals(value0, values.iterator().next()); + + // serializability + assertEquals(m, roundtrip(m, true)); + + // put + assertEquals(value0, m.put(key, value1)); +// m.putAll(); ##### + + // remove + assertEquals(value1, m.put(key, value1)); + assertEquals(value1, m.remove(key)); + m.put(key, value1); + + // ConcurrentMap stuff + ConcurrentMap cm = (ConcurrentMap) m; + assertFalse(cm.remove("invalid key", value0)); + assertTrue(cm.remove(key, value1)); + assertNull(cm.putIfAbsent(key, value0)); // null == prev unset + + // value0 might be null; can't disambiguate from above in OpenJPA + // interpretation + assertEquals(value0, cm.putIfAbsent(key, "invalid value")); + + // replace + assertEquals(value0, cm.replace(key, value1)); + assertTrue(cm.replace(key, value1, value2)); + } + + public void testNullValues() throws ClassNotFoundException, IOException { + Map m = newMap(); + nullValsHelper(m, "foo"); + } + + private void nullValsHelper(Map m, Object key) + throws IOException, ClassNotFoundException { + helper(m, key, null, null, null); + helper(m, key, "bar", "baz", "quux"); + + helper(m, key, "bar", "baz", null); + helper(m, key, null, "baz", "quux"); + helper(m, key, "bar", null, "quux"); + + helper(m, key, "bar", null, null); + helper(m, key, null, "baz", null); + helper(m, key, null, null, "quux"); + } + + public void testNullKeysAndValues() + throws ClassNotFoundException, IOException { + Map m = newMap(); + nullValsHelper(m, null); + } +} Modified: openjpa/trunk/openjpa-persistence-jdbc/pom.xml URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/pom.xml?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/pom.xml (original) +++ openjpa/trunk/openjpa-persistence-jdbc/pom.xml Mon Mar 24 20:37:56 2008 @@ -239,7 +239,7 @@ <dependencies> <dependency> <groupId>org.apache.openjpa</groupId> - <artifactId>openjpa-jdbc-5</artifactId> + <artifactId>openjpa-jdbc</artifactId> <version>${pom.version}</version> <scope>compile</scope> </dependency> Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java Mon Mar 24 20:37:56 2008 @@ -55,7 +55,7 @@ // actually, we really only need redef fail("this test method does not work without enhancement"); - setUp(ExceptionsFromCallbacksEntity.class, CLEAR_TABLES, "openjpa.Log", "SQL=TRACE"); + setUp(ExceptionsFromCallbacksEntity.class, CLEAR_TABLES); testRunning = true; } Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java Mon Mar 24 20:37:56 2008 @@ -205,7 +205,6 @@ map.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true," + "SchemaAction='add,deleteTableContents')"); - map.put("openjpa.Log", "SQL=TRACE"); } protected OpenJPAEntityManagerFactory getEmf() { Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/discriminator/TestDiscriminatorTypes.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/discriminator/TestDiscriminatorTypes.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/discriminator/TestDiscriminatorTypes.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/discriminator/TestDiscriminatorTypes.java Mon Mar 24 20:37:56 2008 @@ -34,7 +34,7 @@ CharRootEntity.class, IntegerAbstractEntity.class, IntegerLeafEntity.class, IntegerRootEntity.class, StringAbstractEntity.class, StringLeafEntity.class, - StringRootEntity.class, CLEAR_TABLES, "openjpa.Log", "SQL=TRACE"); + StringRootEntity.class, CLEAR_TABLES); } public void testCharDiscriminators() { Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java Mon Mar 24 20:37:56 2008 @@ -36,7 +36,7 @@ import org.apache.openjpa.persistence.common.utils.AbstractTestCase; import org.apache.openjpa.jdbc.conf.JDBCConfiguration; -import org.apache.openjpa.lib.util.concurrent.ReentrantLock; +import java.util.concurrent.locks.ReentrantLock; import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory; import org.apache.openjpa.persistence.jdbc.FetchMode; Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java Mon Mar 24 20:37:56 2008 @@ -67,12 +67,6 @@ endEm(pm); } - @Override - protected void addProperties(Map map) { - super.addProperties(map); - map.put("openjpa.Log", "SQL=TRACE, Runtime=TRACE"); - } - public void testRetain() { clearTest(true); optLockTest(true); Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java Mon Mar 24 20:37:56 2008 @@ -29,7 +29,7 @@ public void setUp() { setUp(HandlerToRelationMapInstance.class, AllFieldTypes.class, - CLEAR_TABLES, "openjpa.Log", "SQL=TRACE"); + CLEAR_TABLES); } public void testHandlerToRelationMaps() { Modified: openjpa/trunk/openjpa-persistence/pom.xml URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/pom.xml?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/pom.xml (original) +++ openjpa/trunk/openjpa-persistence/pom.xml Mon Mar 24 20:37:56 2008 @@ -35,7 +35,7 @@ <dependencies> <dependency> <groupId>org.apache.openjpa</groupId> - <artifactId>openjpa-kernel-5</artifactId> + <artifactId>openjpa-kernel</artifactId> <version>${pom.version}</version> <scope>compile</scope> </dependency> Modified: openjpa/trunk/openjpa-xmlstore/pom.xml URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-xmlstore/pom.xml?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/openjpa-xmlstore/pom.xml (original) +++ openjpa/trunk/openjpa-xmlstore/pom.xml Mon Mar 24 20:37:56 2008 @@ -32,26 +32,6 @@ <artifactId>openjpa-parent</artifactId> <version>1.1.0-SNAPSHOT</version> </parent> - <profiles> - <profile> - <id>java14-validate</id> - <activation><property><name>java14.jar</name></property></activation> - <build> - <pluginManagement> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <compilerArguments> - <bootclasspath>${java14.jar}</bootclasspath> - </compilerArguments> - </configuration> - </plugin> - </plugins> - </pluginManagement> - </build> - </profile> - </profiles> <dependencies> <dependency> <groupId>org.apache.openjpa</groupId> @@ -65,8 +45,8 @@ <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> - <source>1.4</source> - <target>1.4</target> + <source>1.5</source> + <target>1.5</target> </configuration> </plugin> </plugins> Modified: openjpa/trunk/pom.xml URL: http://svn.apache.org/viewvc/openjpa/trunk/pom.xml?rev=640685&r1=640684&r2=640685&view=diff ============================================================================== --- openjpa/trunk/pom.xml (original) +++ openjpa/trunk/pom.xml Mon Mar 24 20:37:56 2008 @@ -84,29 +84,17 @@ <module>openjpa-lib</module> <module>openjpa-kernel</module> <module>openjpa-jdbc</module> + <module>openjpa-persistence</module> + <module>openjpa-persistence-jdbc</module> <module>openjpa-xmlstore</module> <module>openjpa-slice</module> <module>openjpa-all</module> <module>openjpa-project</module> + <module>openjpa-examples</module> <module>openjpa-integration</module> </modules> <profiles> <profile> - <id>jdk1.5</id> - <activation> - <jdk>1.5</jdk> - </activation> - <modules> - <module>openjpa-lib-5</module> - <module>openjpa-persistence</module> - <module>openjpa-persistence-jdbc</module> - <module>openjpa-kernel-5</module> - <module>openjpa-jdbc-5</module> - <module>openjpa-slice</module> - <module>openjpa-examples</module> - </modules> - </profile> - <profile> <id>release</id> <activation> <property> @@ -360,7 +348,6 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> - <version>2.4</version> <configuration> <argLine>${surefire.jvm.args}</argLine> <useFile>false</useFile>