You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2012/04/22 19:06:09 UTC

svn commit: r1328904 - in /commons/sandbox/graph/trunk/src: main/java/org/apache/commons/graph/ test/java/org/apache/commons/graph/model/

Author: marcosperanza
Date: Sun Apr 22 17:06:09 2012
New Revision: 1328904

URL: http://svn.apache.org/viewvc?rev=1328904&view=rev
Log:
[SANDBOX-386] Make Graph components Serializable

Added:
    commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java   (with props)
    commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java   (with props)
    commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java   (with props)
    commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java   (with props)
Modified:
    commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/CommonsGraph.java
    commons/sandbox/graph/trunk/src/test/java/org/apache/commons/graph/model/GraphSerializationTestCase.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=1328904&r1=1328903&r2=1328904&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 Sun Apr 22 17:06:09 2012
@@ -19,15 +19,8 @@ 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.InvocationTargetException;
-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;
@@ -208,118 +201,111 @@ public final class CommonsGraph<V, E, G 
     }
 
     /**
-     * Returns a synchronized (thread-safe) {@link Graph} backed by the specified Graph.
-     *
-     * @param graph
-     * @return
+     * Returns a synchronized (thread-safe) {@link Graph} backed by the specified Graph. 
+     * 
+     * It is imperative that the user manually synchronize on the returned graph when iterating over iterable collections: 
+     * <pre>
+     *     Graph syncGraph = synchronize( graph );
+     *         ...
+     *     synchronized(syncGraph) {
+     *         for ( Vertex v : g.getVertices() ) // Must be in synchronized block 
+     *         {
+     *            foo( v )
+     *         }
+     *   }
+     * </pre> 
+     * 
+     * Failure to follow this advice may result in non-deterministic behavior.
+     * 
+     * The returned {@link Graph} will be serializable if the specified {@link Graph} is serializable.
+     *  
+     * @param the input graph
+     * @return the syncronyzed graph
      */
     public static <V, E> Graph<V, E> synchronize( Graph<V, E> graph )
     {
-        return synchronizedObject( graph, Graph.class );
+        return new SynchronizedGraph<V, E>( graph );
     }
 
     /**
      * Returns a synchronized (thread-safe) {@link DirectedGraph} backed by the specified Graph.
-     *
-     * @param graph
-     * @return
+     * 
+     * It is imperative that the user manually synchronize on the returned graph when iterating over iterable collections: 
+     * <pre>
+     *     Graph syncGraph = synchronize( graph );
+     *         ...
+     *     synchronized(syncGraph) {
+     *         for ( Vertex v : g.getVertices() ) // Must be in synchronized block 
+     *         {
+     *            foo( v )
+     *         }
+     *   }
+     * </pre> 
+     * 
+     * Failure to follow this advice may result in non-deterministic behavior.
+     *
+     * The returned {@link Graph} will be serializable if the specified {@link Graph} is serializable.
+     *  
+     * @param the input graph
+     * @return the syncronyzed graph
      */
     public static <V, E> Graph<V, E> synchronize( DirectedGraph<V, E> graph )
     {
-        return synchronizedObject( graph, DirectedGraph.class );
+        return new SynchronizedDirectedGraph<V, E>( graph );
     }
 
     /**
      * Returns a synchronized (thread-safe) {@link UndirectedGraph} backed by the specified Graph.
-     *
-     * @param graph
-     * @return
+     * 
+     * It is imperative that the user manually synchronize on the returned graph when iterating over iterable collections: 
+     * <pre>
+     *     Graph syncGraph = synchronize( graph );
+     *         ...
+     *     synchronized(syncGraph) {
+     *         for ( Vertex v : g.getVertices() ) // Must be in synchronized block 
+     *         {
+     *            foo( v )
+     *         }
+     *   }
+     * </pre> 
+     * 
+     * Failure to follow this advice may result in non-deterministic behavior.
+     * 
+     * The returned {@link Graph} will be serializable if the specified {@link Graph} is serializable.
+     * 
+     * @param the input graph
+     * @return the syncronyzed graph
      */
     public static <V, E> Graph<V, E> synchronize( UndirectedGraph<V, E> graph )
     {
-        return synchronizedObject( graph, UndirectedGraph.class );
+        return new SynchronizedUndirectedGraph<V, E>( graph );
     }
 
     /**
      * Returns a synchronized (thread-safe) {@link MutableGraph} backed by the specified Graph.
-     *
-     * @param graph
-     * @return
+     * 
+     * It is imperative that the user manually synchronize on the returned graph when iterating over iterable collections: 
+     * <pre>
+     *     Graph syncGraph = synchronize( graph );
+     *         ...
+     *     synchronized(syncGraph) {
+     *         for ( Vertex v : g.getVertices() ) // Must be in synchronized block 
+     *         {
+     *            foo( v )
+     *         }
+     *   }
+     * </pre> 
+     * 
+     * Failure to follow this advice may result in non-deterministic behavior.
+     * 
+     * The returned {@link Graph} will be serializable if the specified {@link Graph} is serializable.
+     * 
+     * @param the input graph
+     * @return the syncronyzed graph
      */
     public static <V, E> Graph<V, E> synchronize( MutableGraph<V, E> graph )
     {
-        return synchronizedObject( graph, MutableGraph.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 Graph interface only.
-         */
-        final Set<Method> synchronizedMethods = new HashSet<Method>();
-
-        for ( Method method : type.getDeclaredMethods() )
-        {
-            synchronizedMethods.add( method );
-        }
-        GraphInvocationHandler<T> handler =
-            new GraphInvocationHandler<T>( synchronizedMethods, checkedToBeSynchronized );
-        Object proxy = newProxyInstance( type.getClassLoader(), new Class<?>[] { type }, handler );
-        handler.lock = proxy;
-        return type.cast( proxy );
-    }
-
-    private static class GraphInvocationHandler<T>
-        implements InvocationHandler
-    {
-        protected Object lock;
-
-        private final Set<Method> synchronizedMethods;
-
-        private final T checkedToBeSynchronized;
-
-        public GraphInvocationHandler( Set<Method> synchronizedMethods, T checkedToBeSynchronized )
-        {
-            this.synchronizedMethods = synchronizedMethods;
-            this.checkedToBeSynchronized = checkedToBeSynchronized;
-        }
-
-        public Object invoke( Object proxy, Method method, Object[] args )
-            throws Throwable
-        {
-            if ( synchronizedMethods.contains( method ) )
-            {
-                synchronized ( lock )
-                {
-                    return invoke( method, args );
-                }
-            }
-            return invoke( method, args );
-        }
-
-        private Object invoke( Method method, Object[] args )
-            throws Throwable
-        {
-            try
-            {
-                return method.invoke( checkedToBeSynchronized, args );
-            }
-            catch ( InvocationTargetException e )
-            {
-                throw e.getTargetException();
-            }
-        }
-
+        return new SynchronizedMutableGraph<V, E>( graph );
     }
 
     /**

Added: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java
URL: http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java?rev=1328904&view=auto
==============================================================================
--- commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java (added)
+++ commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java Sun Apr 22 17:06:09 2012
@@ -0,0 +1,74 @@
+package org.apache.commons.graph;
+
+/*
+ * 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.
+ */
+
+/**
+ * 
+ */
+class SynchronizedDirectedGraph<V, E>
+    extends SynchronizedGraph<V, E>
+    implements DirectedGraph<V, E>
+{
+
+    private static final long serialVersionUID = 2275587906693672253L;
+
+    final private DirectedGraph<V, E> directedGraph;
+
+    /**
+     * @param g
+     */
+    public SynchronizedDirectedGraph( DirectedGraph<V, E> g )
+    {
+        super( g );
+        directedGraph = g;
+    }
+
+    public int getInDegree( V v )
+    {
+        synchronized ( lock )
+        {
+            return directedGraph.getInDegree( v );
+        }
+    }
+
+    public Iterable<V> getInbound( V v )
+    {
+        synchronized ( lock )
+        {
+            return directedGraph.getInbound( v );
+        }
+    }
+
+    public int getOutDegree( V v )
+    {
+        synchronized ( lock )
+        {
+            return directedGraph.getOutDegree( v );
+        }
+    }
+
+    public Iterable<V> getOutbound( V v )
+    {
+        synchronized ( lock )
+        {
+            return directedGraph.getOutbound( v );
+        }
+    }
+}

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedDirectedGraph.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java
URL: http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java?rev=1328904&view=auto
==============================================================================
--- commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java (added)
+++ commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java Sun Apr 22 17:06:09 2012
@@ -0,0 +1,160 @@
+package org.apache.commons.graph;
+
+import static org.apache.commons.graph.utils.Objects.eq;
+
+/*
+ * 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.
+ */
+
+/**
+ * 
+ */
+class SynchronizedGraph<V, E>
+    implements Graph<V, E>
+{
+
+    private static final long serialVersionUID = 4472623111635514693L;
+
+    final protected Object lock;
+
+    final protected Graph<V, E> g;
+
+    /**
+     * 
+     */
+    public SynchronizedGraph( Graph<V, E> g )
+    {
+        this.g = g;
+        this.lock = this;
+    }
+
+    public Iterable<V> getVertices()
+    {
+        synchronized ( lock )
+        {
+            return g.getVertices();
+        }
+    }
+
+    public int getOrder()
+    {
+        synchronized ( lock )
+        {
+            return g.getOrder();
+        }
+    }
+
+    public Iterable<E> getEdges()
+    {
+        synchronized ( lock )
+        {
+            return g.getEdges();
+        }
+    }
+
+    public int getSize()
+    {
+        synchronized ( lock )
+        {
+            return g.getSize();
+        }
+    }
+
+    public int getDegree( V v )
+    {
+        synchronized ( lock )
+        {
+            return g.getDegree( v );
+        }
+    }
+
+    public Iterable<V> getConnectedVertices( V v )
+    {
+        synchronized ( lock )
+        {
+            return g.getConnectedVertices( v );
+        }
+    }
+
+    public E getEdge( V source, V target )
+    {
+        synchronized ( lock )
+        {
+            return g.getEdge( source, target );
+        }
+    }
+
+    public VertexPair<V> getVertices( E e )
+    {
+        synchronized ( lock )
+        {
+            return g.getVertices( e );
+        }
+    }
+
+    public boolean containsVertex( V v )
+    {
+        synchronized ( lock )
+        {
+            return g.containsVertex( v );
+        }
+    }
+
+    public boolean containsEdge( E e )
+    {
+        synchronized ( lock )
+        {
+            return g.containsEdge( e );
+        }
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( g == null ) ? 0 : g.hashCode() );
+        result = prime * result + ( ( lock == null ) ? 0 : lock.hashCode() );
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( obj == null || getClass() != obj.getClass() )
+        {
+            return false;
+        }
+
+        @SuppressWarnings( "unchecked" )
+        // test against any Graph typed instance
+        SynchronizedGraph<Object, Object> other = (SynchronizedGraph<Object, Object>) obj;
+        return eq( g, other.g );
+    }
+
+    @Override
+    public String toString()
+    {
+        return g.toString();
+    }
+}

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedGraph.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java
URL: http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java?rev=1328904&view=auto
==============================================================================
--- commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java (added)
+++ commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java Sun Apr 22 17:06:09 2012
@@ -0,0 +1,70 @@
+package org.apache.commons.graph;
+
+/*
+ * 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.
+ */
+
+/**
+ * 
+ */
+class SynchronizedMutableGraph<V, E>
+    extends SynchronizedGraph<V, E>
+    implements MutableGraph<V, E>
+{
+    private static final long serialVersionUID = -5985121601939852063L;
+
+    private MutableGraph<V, E> mutableGraph;
+
+    public SynchronizedMutableGraph( MutableGraph<V, E> g )
+    {
+        super( g );
+        this.mutableGraph = g;
+    }
+
+    public void addVertex( V v )
+    {
+        synchronized ( lock )
+        {
+            mutableGraph.addVertex( v );
+        }
+    }
+
+    public void removeVertex( V v )
+    {
+        synchronized ( lock )
+        {
+            mutableGraph.removeVertex( v );
+        }
+    }
+
+    public void addEdge( V head, E e, V tail )
+    {
+        synchronized ( lock )
+        {
+            mutableGraph.addEdge( head, e, tail );
+        }
+    }
+
+    public void removeEdge( E e )
+    {
+        synchronized ( lock )
+        {
+            mutableGraph.removeEdge( e );
+        }
+    }
+}

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedMutableGraph.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java
URL: http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java?rev=1328904&view=auto
==============================================================================
--- commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java (added)
+++ commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java Sun Apr 22 17:06:09 2012
@@ -0,0 +1,40 @@
+package org.apache.commons.graph;
+
+/*
+ * 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.
+ */
+
+/**
+ * 
+ */
+class SynchronizedUndirectedGraph<V, E>
+    extends SynchronizedGraph<V, E>
+    implements UndirectedGraph<V, E>
+{
+
+    private static final long serialVersionUID = 2207884889346410427L;
+
+    /**
+     * @param g
+     */
+    public SynchronizedUndirectedGraph( Graph<V, E> g )
+    {
+        super( g );
+    }
+
+}

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/SynchronizedUndirectedGraph.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: commons/sandbox/graph/trunk/src/test/java/org/apache/commons/graph/model/GraphSerializationTestCase.java
URL: http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/test/java/org/apache/commons/graph/model/GraphSerializationTestCase.java?rev=1328904&r1=1328903&r2=1328904&view=diff
==============================================================================
--- commons/sandbox/graph/trunk/src/test/java/org/apache/commons/graph/model/GraphSerializationTestCase.java (original)
+++ commons/sandbox/graph/trunk/src/test/java/org/apache/commons/graph/model/GraphSerializationTestCase.java Sun Apr 22 17:06:09 2012
@@ -116,6 +116,16 @@ public class GraphSerializationTestCase
     }
 
     @Test
+    public void serializeSyncronyzedDirectedWeightdGraph()
+        throws Exception
+    {
+        Graph<BaseLabeledVertex, BaseLabeledWeightedEdge<Double>> g =
+            CommonsGraph.synchronize( (MutableGraph<BaseLabeledVertex, BaseLabeledWeightedEdge<Double>>) newDirectedMutableGraph( buildWeightedGraphConnections() ) );
+
+        checkSerialization( g );
+    }
+
+    @Test
     public void serializePath()
         throws Exception
     {