You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by si...@apache.org on 2012/03/02 22:16:46 UTC
svn commit: r1296479 -
/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java
Author: simonetripodi
Date: Fri Mar 2 21:16:46 2012
New Revision: 1296479
URL: http://svn.apache.org/viewvc?rev=1296479&view=rev
Log:
[SANDBOX-400] first implementation of methods to synchronize existing Graph data structures to make them thread-safe
Modified:
commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java
Modified: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java
URL: http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java?rev=1296479&r1=1296478&r2=1296479&view=diff
==============================================================================
--- commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java (original)
+++ commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java Fri Mar 2 21:16:46 2012
@@ -19,8 +19,14 @@ package org.apache.commons.graph;
* under the License.
*/
+import static java.lang.reflect.Proxy.newProxyInstance;
import static org.apache.commons.graph.utils.Assertions.checkNotNull;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
import org.apache.commons.graph.builder.DefaultLinkedConnectionBuilder;
import org.apache.commons.graph.builder.GraphConnection;
import org.apache.commons.graph.builder.LinkedConnectionBuilder;
@@ -210,6 +216,105 @@ public final class CommonsGraph<V extend
}
/**
+ * Returns a synchronized (thread-safe) {@link Graph} backed by the specified Graph.
+ *
+ * @param graph
+ * @return
+ */
+ public static <V extends Vertex, E extends Edge> Graph<V, E> synchronize( Graph<V, E> graph )
+ {
+ return synchronizedObject( graph, Graph.class );
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@link DirectedGraph} backed by the specified Graph.
+ *
+ * @param graph
+ * @return
+ */
+ public static <V extends Vertex, E extends Edge> Graph<V, E> synchronize( DirectedGraph<V, E> graph )
+ {
+ return synchronizedObject( graph, DirectedGraph.class );
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@link UndirectedGraph} backed by the specified Graph.
+ *
+ * @param graph
+ * @return
+ */
+ public static <V extends Vertex, E extends Edge> Graph<V, E> synchronize( UndirectedGraph<V, E> graph )
+ {
+ return synchronizedObject( graph, UndirectedGraph.class );
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@link MutableGraph} backed by the specified Graph.
+ *
+ * @param graph
+ * @return
+ */
+ public static <V extends Vertex, E extends Edge> Graph<V, E> synchronize( MutableGraph<V, E> graph )
+ {
+ return synchronizedObject( graph, MutableGraph.class );
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@link WeightedGraph} backed by the specified Graph.
+ *
+ * @param graph
+ * @return
+ */
+ public static <V extends Vertex, WE extends WeightedEdge<W>, W> Graph<V, WE> synchronize( WeightedGraph<V, WE, W> graph )
+ {
+ return synchronizedObject( graph, WeightedGraph.class );
+ }
+
+ /**
+ * Wrap the given object in a proxed one where all methods declared in the given interface will be synchronized.
+ *
+ * @param <T> the object type has to be proxed
+ * @param toBeSynchronized to object which methods have to be synchronized
+ * @param type the interface has to be proxed
+ * @return the dynamic synchronized proxy
+ */
+ private static <T> T synchronizedObject( T toBeSynchronized, final Class<T> type )
+ {
+ final T checkedToBeSynchronized = checkNotNull( toBeSynchronized, "Impossible to synchronize a null graph!" );
+
+ /*
+ * Used to synchronize method declared on the pool/factory interface only.
+ */
+ final Set<Method> synchronizedMethods = new HashSet<Method>();
+
+ for ( Method method : type.getDeclaredMethods() )
+ {
+ synchronizedMethods.add( method );
+ }
+
+ return type.cast( newProxyInstance( type.getClassLoader(), new Class<?>[] { type },
+ new InvocationHandler()
+ {
+
+ private final Object lock = new Object();
+
+ public Object invoke( Object proxy, Method method, Object[] args )
+ throws Throwable
+ {
+ if ( synchronizedMethods.contains( method ) )
+ {
+ synchronized ( this.lock )
+ {
+ return method.invoke( checkedToBeSynchronized, args );
+ }
+ }
+ return method.invoke( checkedToBeSynchronized, args );
+ }
+
+ } ) );
+ }
+
+ /**
* Hidden constructor, this class cannot be instantiated.
*/
private CommonsGraph()