You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2012/06/06 19:08:15 UTC
[1/2] git commit: TAP5-1929: Convert more synchronized blocks to
ReentrantReadWriteLock
Updated Branches:
refs/heads/5.3 63fe85d14 -> bb940c080
TAP5-1929: Convert more synchronized blocks to ReentrantReadWriteLock
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/bb940c08
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/bb940c08
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/bb940c08
Branch: refs/heads/5.3
Commit: bb940c080f77856b520fd39b28c38d38b5609c1f
Parents: 15477fd
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Wed Jun 6 10:08:02 2012 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Wed Jun 6 10:08:02 2012 -0700
----------------------------------------------------------------------
.../internal/services/ContextResource.java | 7 +-
.../ioc/internal/services/TypeCoercerImpl.java | 168 ++++++++++-----
.../ioc/internal/util/AbstractResource.java | 30 +---
.../ioc/internal/util/ClasspathResource.java | 6 +-
.../tapestry5/ioc/internal/util/LockSupport.java | 85 ++++++++
.../tapestry5/ioc/internal/util/OneShotLock.java | 36 +++-
.../tapestry5/ioc/services/CoercionTuple.java | 30 ++--
.../tapestry5/ioc/services/TapestryIOCModule.java | 4 +-
8 files changed, 251 insertions(+), 115 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextResource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextResource.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextResource.java
index 681424f..f5337b2 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextResource.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextResource.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008, 2010 The Apache Software Foundation
+// Copyright 2006, 2008, 2010, 2012 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.
@@ -62,8 +62,7 @@ public class ContextResource extends AbstractResource
{
try
{
- lock.readLock().lock();
-
+ acquireReadLock();
if (!urlResolved)
{
resolveURL();
@@ -73,7 +72,7 @@ public class ContextResource extends AbstractResource
} finally
{
- lock.readLock().unlock();
+ releaseReadLock();
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
index f92f88c..ba40500 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2010 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010, 2012 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.
@@ -14,28 +14,23 @@
package org.apache.tapestry5.ioc.internal.services;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-
import org.apache.tapestry5.func.F;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InheritanceSearch;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.services.ClassFabUtils;
+import org.apache.tapestry5.ioc.internal.util.LockSupport;
import org.apache.tapestry5.ioc.services.Coercion;
import org.apache.tapestry5.ioc.services.CoercionTuple;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.ioc.util.AvailableValues;
import org.apache.tapestry5.ioc.util.UnknownValueException;
+import org.apache.tapestry5.plastic.PlasticUtils;
import org.apache.tapestry5.util.StringToEnumCoercion;
+import java.util.*;
+
@SuppressWarnings("all")
-public class TypeCoercerImpl implements TypeCoercer
+public class TypeCoercerImpl extends LockSupport implements TypeCoercer
{
// Constructed from the service's configuration.
@@ -62,19 +57,19 @@ public class TypeCoercerImpl implements TypeCoercer
Object coerce(Object input)
{
-
- Class sourceType = input != null ? input.getClass() : void.class;
+ Class sourceType = input != null ? input.getClass() : Void.class;
if (type.isAssignableFrom(sourceType))
+ {
return input;
+ }
Coercion c = getCoercion(sourceType);
try
{
return type.cast(c.coerce(input));
- }
- catch (Exception ex)
+ } catch (Exception ex)
{
throw new RuntimeException(ServiceMessages.failedCoercion(input, type, c, ex), ex);
}
@@ -94,6 +89,7 @@ public class TypeCoercerImpl implements TypeCoercer
c = findOrCreateCoercion(sourceType, type);
cache.put(sourceType, c);
}
+
return c;
}
}
@@ -139,10 +135,13 @@ public class TypeCoercerImpl implements TypeCoercer
public Object coerce(Object input, Class targetType)
{
assert targetType != null;
- Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
+ Class effectiveTargetType = PlasticUtils.toWrapperType(targetType);
if (effectiveTargetType.isInstance(input))
+ {
return input;
+ }
+
return getTargetCoercion(effectiveTargetType).coerce(input);
}
@@ -152,11 +151,13 @@ public class TypeCoercerImpl implements TypeCoercer
{
assert sourceType != null;
assert targetType != null;
- Class effectiveSourceType = ClassFabUtils.getWrapperType(sourceType);
- Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
+ Class effectiveSourceType = PlasticUtils.toWrapperType(sourceType);
+ Class effectiveTargetType = PlasticUtils.toWrapperType(targetType);
if (effectiveTargetType.isAssignableFrom(effectiveSourceType))
+ {
return NO_COERCION;
+ }
return getTargetCoercion(effectiveTargetType).getCoercion(effectiveSourceType);
}
@@ -166,43 +167,78 @@ public class TypeCoercerImpl implements TypeCoercer
{
assert sourceType != null;
assert targetType != null;
- Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
- Class effectiveSourceType = ClassFabUtils.getWrapperType(sourceType);
+ Class effectiveTargetType = PlasticUtils.toWrapperType(targetType);
+ Class effectiveSourceType = PlasticUtils.toWrapperType(sourceType);
// Is a coercion even necessary? Not if the target type is assignable from the
// input value.
if (effectiveTargetType.isAssignableFrom(effectiveSourceType))
+ {
return "";
+ }
- return getTargetCoercion(targetType).explain(sourceType);
+ return getTargetCoercion(effectiveTargetType).explain(effectiveSourceType);
}
- private synchronized TargetCoercion getTargetCoercion(Class targetType)
+ private TargetCoercion getTargetCoercion(Class targetType)
{
- TargetCoercion tc = typeToTargetCoercion.get(targetType);
+ try
+ {
+ acquireReadLock();
- if (tc == null)
+ TargetCoercion tc = typeToTargetCoercion.get(targetType);
+
+ return tc != null ? tc : createAndStoreNewTargetCoercion(targetType);
+ } finally
{
- tc = new TargetCoercion(targetType);
- typeToTargetCoercion.put(targetType, tc);
+ releaseReadLock();
}
-
- return tc;
}
- public synchronized void clearCache()
+ private TargetCoercion createAndStoreNewTargetCoercion(Class targetType)
{
- // There's no need to clear the typeToTargetCoercion map, as it is a WeakHashMap and
- // will release the keys for classes that are no longer in existence. On the other hand,
- // there's likely all sorts of references to unloaded classes inside each TargetCoercion's
- // individual cache, so clear all those.
+ try
+ {
+ upgradeReadLockToWriteLock();
+
+ // Inner check since some other thread may have beat us to it.
+
+ TargetCoercion tc = typeToTargetCoercion.get(targetType);
+
+ if (tc == null)
+ {
+ tc = new TargetCoercion(targetType);
+ typeToTargetCoercion.put(targetType, tc);
+ }
- for (TargetCoercion tc : typeToTargetCoercion.values())
+ return tc;
+ } finally
{
- // Can tc ever be null?
+ downgradeWriteLockToReadLock();
+ }
+ }
+
+ public void clearCache()
+ {
+ try
+ {
+ acquireReadLock();
+
+ // There's no need to clear the typeToTargetCoercion map, as it is a WeakHashMap and
+ // will release the keys for classes that are no longer in existence. On the other hand,
+ // there's likely all sorts of references to unloaded classes inside each TargetCoercion's
+ // individual cache, so clear all those.
- tc.clearCache();
+ for (TargetCoercion tc : typeToTargetCoercion.values())
+ {
+ // Can tc ever be null?
+
+ tc.clearCache();
+ }
+ } finally
+ {
+ releaseReadLock();
}
}
@@ -219,13 +255,13 @@ public class TypeCoercerImpl implements TypeCoercer
* tuples are added to the queue, there are two factors: size (the number of steps in the coercion) and
* "class distance" (that is, number of steps up the inheritance hiearchy). All the appropriate 1 step coercions
* will be considered first, in class distance order. Along the way, we'll queue up all the 2 step coercions, again
- * in class distance order. By the time we reach some of those, we'll have begun queing up the 3 step coercions, and
+ * in class distance order. By the time we reach some of those, we'll have begun queueing up the 3 step coercions, and
* so forth, until we run out of input tuples we can use to fabricate multi-step compound coercions, or reach a
* final response.
* <p/>
* This does create a good number of short lived temporary objects (the compound tuples), but that's what the GC is
* really good at.
- *
+ *
* @param sourceType
* @param targetType
* @return coercer from sourceType to targetType
@@ -233,8 +269,10 @@ public class TypeCoercerImpl implements TypeCoercer
@SuppressWarnings("unchecked")
private Coercion findOrCreateCoercion(Class sourceType, Class targetType)
{
- if (sourceType == void.class)
+ if (sourceType == Void.class)
+ {
return searchForNullCoercion(targetType);
+ }
// These are instance variables because this method may be called concurrently.
// On a true race, we may go to the work of seeking out and/or fabricating
@@ -259,7 +297,9 @@ public class TypeCoercerImpl implements TypeCoercer
Class tupleTargetType = tuple.getTargetType();
if (targetType.isAssignableFrom(tupleTargetType))
+ {
return tuple.getCoercion();
+ }
// So .. this tuple doesn't get us directly to the target type.
// However, it *may* get us part of the way. Each of these
@@ -281,14 +321,14 @@ public class TypeCoercerImpl implements TypeCoercer
* Coercion from null is special; we match based on the target type and its not a spanning
* search. In many cases, we
* return a pass-thru that leaves the value as null.
- *
+ *
* @param targetType
- * desired type
+ * desired type
* @return the coercion
*/
private Coercion searchForNullCoercion(Class targetType)
{
- List<CoercionTuple> tuples = getTuples(void.class, targetType);
+ List<CoercionTuple> tuples = getTuples(Void.class, targetType);
for (CoercionTuple tuple : tuples)
{
@@ -325,7 +365,7 @@ public class TypeCoercerImpl implements TypeCoercer
* Seeds the pool with the initial set of coercions for the given type.
*/
private void seedQueue(Class sourceType, Class targetType, Set<CoercionTuple> consideredTuples,
- LinkedList<CoercionTuple> queue)
+ LinkedList<CoercionTuple> queue)
{
// Work from the source type up looking for tuples
@@ -334,7 +374,9 @@ public class TypeCoercerImpl implements TypeCoercer
List<CoercionTuple> tuples = getTuples(c, targetType);
if (tuples == null)
+ {
continue;
+ }
for (CoercionTuple tuple : tuples)
{
@@ -345,8 +387,10 @@ public class TypeCoercerImpl implements TypeCoercer
// Don't pull in Object -> type coercions when doing
// a search from null.
- if (sourceType == void.class)
+ if (sourceType == Void.class)
+ {
return;
+ }
}
}
@@ -354,23 +398,23 @@ public class TypeCoercerImpl implements TypeCoercer
* Creates and adds to the pool a new set of coercions based on an intermediate tuple. Adds
* compound coercion tuples
* to the end of the queue.
- *
+ *
* @param sourceType
- * the source type of the coercion
+ * the source type of the coercion
* @param targetType
- * TODO
+ * TODO
* @param intermediateTuple
- * a tuple that converts from the source type to some intermediate type (that is not
- * assignable to the target type)
+ * a tuple that converts from the source type to some intermediate type (that is not
+ * assignable to the target type)
* @param consideredTuples
- * set of tuples that have already been added to the pool (directly, or as a compound
- * coercion)
+ * set of tuples that have already been added to the pool (directly, or as a compound
+ * coercion)
* @param queue
- * the work queue of tuples
+ * the work queue of tuples
*/
@SuppressWarnings("unchecked")
private void queueIntermediates(Class sourceType, Class targetType, CoercionTuple intermediateTuple,
- Set<CoercionTuple> consideredTuples, LinkedList<CoercionTuple> queue)
+ Set<CoercionTuple> consideredTuples, LinkedList<CoercionTuple> queue)
{
Class intermediateType = intermediateTuple.getTargetType();
@@ -379,7 +423,9 @@ public class TypeCoercerImpl implements TypeCoercer
for (CoercionTuple tuple : getTuples(c, targetType))
{
if (consideredTuples.contains(tuple))
+ {
continue;
+ }
Class newIntermediateType = tuple.getTargetType();
@@ -389,7 +435,9 @@ public class TypeCoercerImpl implements TypeCoercer
// eventually be considered and discarded.
if (sourceType.isAssignableFrom(newIntermediateType))
+ {
continue;
+ }
// The intermediateTuple coercer gets from S --> I1 (an intermediate type).
// The current tuple's coercer gets us from I2 --> X. where I2 is assignable
@@ -413,11 +461,11 @@ public class TypeCoercerImpl implements TypeCoercer
/**
* Returns a non-null list of the tuples from the source type.
- *
+ *
* @param sourceType
- * used to locate tuples
+ * used to locate tuples
* @param targetType
- * used to add synthetic tuples
+ * used to add synthetic tuples
* @return non-null list of tuples
*/
private List<CoercionTuple> getTuples(Class sourceType, Class targetType)
@@ -425,17 +473,21 @@ public class TypeCoercerImpl implements TypeCoercer
List<CoercionTuple> tuples = sourceTypeToTuple.get(sourceType);
if (tuples == null)
+ {
tuples = Collections.emptyList();
+ }
// So, when we see String and an Enum type, we add an additional synthetic tuple to the end
// of the real list. This is the easiest way to accomplish this is a thread-safe and class-reloading
// safe way (i.e., what if the Enum is defined by a class loader that gets discarded? Don't want to cause
// memory leaks by retaining an instance). In any case, there are edge cases where we may create
// the tuple unnecessarily (such as when an explicit string-to-enum coercion is part of the TypeCoercer
- // configuration), but on the whole, this is cheap at works.
-
+ // configuration), but on the whole, this is cheap and works.
+
if (sourceType == String.class && Enum.class.isAssignableFrom(targetType))
+ {
tuples = extend(tuples, new CoercionTuple(sourceType, targetType, new StringToEnumCoercion(targetType)));
+ }
return tuples;
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/AbstractResource.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/AbstractResource.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/AbstractResource.java
index f873eec..d382ba2 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/AbstractResource.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/AbstractResource.java
@@ -22,13 +22,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Locale;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Abstract implementation of {@link Resource}. Subclasses must implement the abstract methods {@link Resource#toURL()}
* and {@link #newResource(String)} as well as toString(), hashCode() and equals().
*/
-public abstract class AbstractResource implements Resource
+public abstract class AbstractResource extends LockSupport implements Resource
{
private class Localization
{
@@ -48,11 +47,6 @@ public abstract class AbstractResource implements Resource
private final String path;
- /**
- * A lock used to when lazily computing other values.
- */
- protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-
// Guarded by Lock
private boolean exists, existsComputed;
@@ -129,7 +123,7 @@ public abstract class AbstractResource implements Resource
{
try
{
- lock.readLock().lock();
+ acquireReadLock();
for (Localization l = firstLocalization; l != null; l = l.next)
{
@@ -142,7 +136,7 @@ public abstract class AbstractResource implements Resource
return populateLocalizationCache(locale);
} finally
{
- lock.readLock().unlock();
+ releaseReadLock();
}
}
@@ -174,20 +168,6 @@ public abstract class AbstractResource implements Resource
}
}
- protected final void upgradeReadLockToWriteLock()
- {
- lock.readLock().unlock();
- // This is that instant where another thread may grab the write lock. Very rare, but possible.
- lock.writeLock().lock();
- }
-
- protected final void downgradeWriteLockToReadLock()
- {
-
- lock.readLock().lock();
- lock.writeLock().unlock();
- }
-
private Resource findLocalizedResource(Locale locale)
{
for (String path : new LocalizedNameGenerator(this.path, locale))
@@ -231,7 +211,7 @@ public abstract class AbstractResource implements Resource
{
try
{
- lock.readLock().lock();
+ acquireReadLock();
if (!existsComputed)
{
@@ -241,7 +221,7 @@ public abstract class AbstractResource implements Resource
return exists;
} finally
{
- lock.readLock().unlock();
+ releaseReadLock();
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ClasspathResource.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ClasspathResource.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ClasspathResource.java
index a6d21ae..a7e613d 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ClasspathResource.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ClasspathResource.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2012 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.
@@ -54,7 +54,7 @@ public final class ClasspathResource extends AbstractResource
{
try
{
- lock.readLock().lock();
+ acquireReadLock();
if (!urlResolved)
{
@@ -64,7 +64,7 @@ public final class ClasspathResource extends AbstractResource
return url;
} finally
{
- lock.readLock().unlock();
+ releaseReadLock();
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/LockSupport.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/LockSupport.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/LockSupport.java
new file mode 100644
index 0000000..5b1cc4f
--- /dev/null
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/LockSupport.java
@@ -0,0 +1,85 @@
+// Copyright 2012 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.tapestry5.ioc.internal.util;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Base class for classes that need to manage a ReadWriteLock.
+ */
+public abstract class LockSupport
+{
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+ private final Lock readLock = lock.readLock();
+
+ private final Lock writeLock = lock.writeLock();
+
+ /**
+ * Locks the shared read lock. Any number of threads may lock the read lock at the same time.
+ */
+ protected final void acquireReadLock()
+ {
+ readLock.lock();
+ }
+
+ /**
+ * Takes the exclusive write lock. Once started, no other thread lock the read or write lock. When this method returns,
+ * this thread will have locked the write lock and no other thread will have either the read or write lock.
+ * Note that this thread must first drop the read lock (if it has it) before attempting to take the write lock, or this method will block forever.
+ */
+ protected final void takeWriteLock()
+ {
+ writeLock.lock();
+ }
+
+ /**
+ * Releases the shared read lock.
+ */
+ protected final void releaseReadLock()
+ {
+ readLock.unlock();
+ }
+
+ /**
+ * Releases the exclusive read lock.
+ */
+ protected final void releaseWriteLock()
+ {
+ writeLock.unlock();
+ }
+
+ /**
+ * Releases the read lock, then takes the write lock. There's a short window where the thread will have neither lock:
+ * during that window, some other thread may have a chance to take the write lock. In code, you'll often see a second check
+ * inside the code that has the write lock to see if the update to perform is still necessary.
+ */
+ protected final void upgradeReadLockToWriteLock()
+ {
+ releaseReadLock();
+ // This is that instant where another thread may grab the write lock. Very rare, but possible.
+ takeWriteLock();
+ }
+
+ /**
+ * Takes the read lock then releases the write lock.
+ */
+ protected final void downgradeWriteLockToReadLock()
+ {
+ acquireReadLock();
+ releaseWriteLock();
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/OneShotLock.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/OneShotLock.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/OneShotLock.java
index 059f258..1b27341 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/OneShotLock.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/OneShotLock.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2012 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.
@@ -18,18 +18,27 @@ package org.apache.tapestry5.ioc.internal.util;
* Logic for handling one shot semantics for classes; classes that include a method (or methods) that "locks down" the
* instance, to prevent it from being used again in the future.
*/
-public class OneShotLock
+public class OneShotLock extends LockSupport
{
private boolean lock;
/**
* Checks to see if the lock has been set (via {@link #lock()}).
*
- * @throws IllegalStateException if the lock is set
+ * @throws IllegalStateException
+ * if the lock is set
*/
- public synchronized void check()
+ public void check()
{
- innerCheck();
+ try
+ {
+ acquireReadLock();
+
+ innerCheck();
+ } finally
+ {
+ releaseReadLock();
+ }
}
private void innerCheck()
@@ -38,12 +47,13 @@ public class OneShotLock
{
// The depth to find the caller of the check() or lock() method varies between JDKs.
-
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
int i = 0;
while (!elements[i].getMethodName().equals("innerCheck"))
+ {
i++;
+ }
throw new IllegalStateException(UtilMessages.oneShotLock(elements[i + 2]));
}
@@ -52,10 +62,18 @@ public class OneShotLock
/**
* Checks the lock, then sets it.
*/
- public synchronized void lock()
+ public void lock()
{
- innerCheck();
+ try
+ {
+ takeWriteLock();
+
+ innerCheck();
- lock = true;
+ lock = true;
+ } finally
+ {
+ releaseWriteLock();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
index bfc146d..8658686 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010, 2011, 2012 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.
@@ -14,6 +14,8 @@
package org.apache.tapestry5.ioc.services;
+import org.apache.tapestry5.plastic.PlasticUtils;
+
/**
* An immutable object that represents a mapping from one type to another. This is also the contribution type when
* building the {@link org.apache.tapestry5.ioc.services.TypeCoercer} service. Wraps a
@@ -21,11 +23,11 @@ package org.apache.tapestry5.ioc.services;
* describe
* the input and output types of the coercion, needed when searching for an appropriate coercion (or sequence of
* coercions).
- *
+ *
* @param <S>
- * source (input) type
+ * source (input) type
* @param <T>
- * target (output) type
+ * target (output) type
*/
public final class CoercionTuple<S, T>
{
@@ -61,10 +63,10 @@ public final class CoercionTuple<S, T>
private String convert(Class type)
{
- if (void.class.equals(type))
+ if (Void.class.equals(type))
return "null";
- String name = ClassFabUtils.toJavaClassName(type);
+ String name = PlasticUtils.toTypeName(type);
int dotx = name.lastIndexOf('.');
@@ -86,7 +88,7 @@ public final class CoercionTuple<S, T>
/**
* Convenience constructor to help with generics.
- *
+ *
* @since 5.2.0
*/
public static <S, T> CoercionTuple<S, T> create(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion)
@@ -96,15 +98,15 @@ public final class CoercionTuple<S, T>
/**
* Internal-use constructor.
- *
+ *
* @param sourceType
- * the source (or input) type of the coercion
+ * the source (or input) type of the coercion, may be Void.class to indicate a coercion from null
* @param targetType
- * the target (or output) type of the coercion
+ * the target (or output) type of the coercion
* @param coercion
- * the object that performs the coercion
+ * the object that performs the coercion
* @param wrap
- * if true, the coercion is wrapped to provide a useful toString()
+ * if true, the coercion is wrapped to provide a useful toString()
*/
@SuppressWarnings("unchecked")
public CoercionTuple(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion, boolean wrap)
@@ -113,8 +115,8 @@ public final class CoercionTuple<S, T>
assert targetType != null;
assert coercion != null;
- this.sourceType = ClassFabUtils.getWrapperType(sourceType);
- this.targetType = ClassFabUtils.getWrapperType(targetType);
+ this.sourceType = PlasticUtils.toWrapperType(sourceType);
+ this.targetType = PlasticUtils.toWrapperType(targetType);
this.coercion = wrap ? new CoercionWrapper<S, T>(coercion) : coercion;
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/bb940c08/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
index c809520..25e9231 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 The Apache Software Foundation
+// Copyright 2006-2012 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.
@@ -313,7 +313,7 @@ public final class TapestryIOCModule
}
});
- add(configuration, void.class, Boolean.class, new Coercion<Void, Boolean>()
+ add(configuration, Void.class, Boolean.class, new Coercion<Void, Boolean>()
{
public Boolean coerce(Void input)
{