You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2010/08/30 13:52:38 UTC

svn commit: r990775 [2/2] - in /cayenne/main/trunk: ./ assembly/src/main/resources/assemblies/ docs/doc/ framework/cayenne-jdk1.5-unpublished/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ framework/cayenne-jdk1.5-unpubl...

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/IndegreeTopologicalSort.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/IndegreeTopologicalSort.java?rev=990775&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/IndegreeTopologicalSort.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/IndegreeTopologicalSort.java Mon Aug 30 11:52:36 2010
@@ -0,0 +1,129 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+/* ====================================================================
+ *
+ * Copyright(c) 2003, Andriy Shapochka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * 3. Neither the name of the ASHWOOD nor the
+ *    names of its contributors may be used to endorse or
+ *    promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by
+ * individuals on behalf of the ASHWOOD Project and was originally
+ * created by Andriy Shapochka.
+ *
+ */
+package org.apache.cayenne.ashwood.graph;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+public class IndegreeTopologicalSort<E, V> extends Algorithm<E> {
+
+    private Digraph<E, V> digraph;
+    private List<E> vertices = new LinkedList<E>();
+    private Map<E, InDegree> inDegrees = new HashMap<E, InDegree>();
+    private ListIterator<E> current;
+
+    public IndegreeTopologicalSort(Digraph<E, V> digraph) {
+        this.digraph = digraph;
+        for (Iterator<E> i = digraph.vertexIterator(); i.hasNext();) {
+            E vertex = i.next();
+            vertices.add(vertex);
+            inDegrees.put(vertex, new InDegree(digraph.incomingSize(vertex)));
+        }
+        current = vertices.listIterator();
+    }
+
+    @Override
+    public boolean hasNext() {
+        return !vertices.isEmpty();
+    }
+
+    @Override
+    public E next() {
+        boolean progress = true;
+        while (hasNext()) {
+            if (!current.hasNext()) {
+                if (!progress)
+                    break;
+                progress = false;
+                current = vertices.listIterator();
+            }
+            E vertex = current.next();
+            InDegree indegree = inDegrees.get(vertex);
+            if (indegree.value == 0) {
+                removeVertex(vertex);
+                current.remove();
+                return vertex;
+            }
+        }
+        return null;
+    }
+
+    private void removeVertex(E vertex) {
+        for (ArcIterator<E, V> i = digraph.outgoingIterator(vertex); i.hasNext();) {
+            i.next();
+            E dst = i.getDestination();
+            InDegree indegree = inDegrees.get(dst);
+            indegree.value--;
+        }
+    }
+
+    private static class InDegree {
+
+        int value;
+
+        InDegree(int value) {
+            InDegree.this.value = value;
+        }
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/MapDigraph.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/MapDigraph.java?rev=990775&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/MapDigraph.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/MapDigraph.java Mon Aug 30 11:52:36 2010
@@ -0,0 +1,404 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+/* ====================================================================
+ *
+ * Copyright(c) 2003, Andriy Shapochka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * 3. Neither the name of the ASHWOOD nor the
+ *    names of its contributors may be used to endorse or
+ *    promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by
+ * individuals on behalf of the ASHWOOD Project and was originally
+ * created by Andriy Shapochka.
+ *
+ */
+package org.apache.cayenne.ashwood.graph;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class MapDigraph<E, V> implements Digraph<E, V> {
+
+    private Map<E, Map<E, V>> graph;
+    private int size;
+
+    public MapDigraph() {
+        graph = new HashMap<E, Map<E, V>>();
+    }
+
+    public boolean addVertex(E vertex) {
+        if (graph.containsKey(vertex)) {
+            return false;
+        }
+
+        graph.put(vertex, new HashMap<E, V>());
+        return true;
+    }
+
+    public boolean addAllVertices(Collection<? extends E> vertices) {
+        if (graph.keySet().containsAll(vertices)) {
+            return false;
+        }
+
+        for (E vertex : vertices) {
+            addVertex(vertex);
+        }
+
+        return true;
+    }
+
+    public V putArc(E origin, E destination, V arc) {
+        Map<E, V> destinations = graph.get(origin);
+        if (destinations == null) {
+            destinations = new HashMap<E, V>();
+            graph.put(origin, destinations);
+        }
+
+        addVertex(destination);
+        V oldArc = destinations.put(destination, arc);
+        if (oldArc == null) {
+            size++;
+        }
+
+        return oldArc;
+    }
+
+    public V getArc(Object origin, Object destination) {
+        Map<E, V> destinations = graph.get(origin);
+        if (destinations == null) {
+            return null;
+        }
+
+        return destinations.get(destination);
+    }
+
+    public boolean removeVertex(E vertex) {
+        Map<E, V> destination = graph.remove(vertex);
+        if (destination != null)
+            size -= destination.size();
+        else
+            return false;
+
+        removeIncoming(vertex);
+        return true;
+    }
+
+    public boolean removeAllVertices(Collection<? extends E> vertices) {
+        boolean modified = false;
+
+        for (E vertex : vertices) {
+            modified |= removeVertex(vertex);
+        }
+
+        return modified;
+    }
+
+    public Object removeArc(E origin, E destination) {
+        Map<E, V> destinations = graph.get(origin);
+        if (destinations == null) {
+            return null;
+        }
+
+        V arc = destinations.remove(destination);
+        if (arc != null)
+            size--;
+
+        return arc;
+    }
+
+    public boolean removeIncoming(E vertex) {
+        boolean modified = false;
+
+        for (Map<E, V> destinations : graph.values()) {
+            Object arc = destinations.remove(vertex);
+            if (arc != null)
+                size--;
+            modified |= (arc != null);
+        }
+
+        return modified;
+    }
+
+    public boolean removeOutgoing(E vertex) {
+
+        Map<E, V> destinations = graph.remove(vertex);
+        if (destinations != null)
+            size -= destinations.size();
+        else
+            return false;
+        boolean modified = !destinations.isEmpty();
+        destinations.clear();
+        return modified;
+    }
+
+    public Iterator<E> vertexIterator() {
+        return graph.keySet().iterator();
+    }
+
+    public ArcIterator<E, V> arcIterator() {
+        return new AllArcIterator();
+    }
+
+    public ArcIterator<E, V> outgoingIterator(E vertex) {
+        if (!containsVertex(vertex)) {
+            return ArcIterator.EMPTY_ITERATOR;
+        }
+
+        return new OutgoingArcIterator(vertex);
+    }
+
+    public ArcIterator<E, V> incomingIterator(E vertex) {
+        if (!containsVertex(vertex))
+            return ArcIterator.EMPTY_ITERATOR;
+        return new IncomingArcIterator(vertex);
+    }
+
+    public int order() {
+        return graph.size();
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public int outgoingSize(E vertex) {
+        Map<E, V> destinations = graph.get(vertex);
+        if (destinations == null)
+            return 0;
+        else
+            return destinations.size();
+    }
+
+    public int incomingSize(E vertex) {
+        int count = 0;
+        if (!graph.containsKey(vertex))
+            return 0;
+
+        for (Map<E, V> destinations : graph.values()) {
+            count += (destinations.containsKey(vertex) ? 1 : 0);
+        }
+
+        return count;
+    }
+
+    public boolean containsVertex(E vertex) {
+        return graph.containsKey(vertex);
+    }
+
+    public boolean containsAllVertices(Collection<? extends E> vertices) {
+        return graph.keySet().containsAll(vertices);
+    }
+
+    public boolean hasArc(E origin, E destination) {
+        Map<E, V> destinations = graph.get(origin);
+        if (destinations == null)
+            return false;
+        return destinations.containsKey(destination);
+    }
+
+    public boolean isEmpty() {
+        return graph.isEmpty();
+    }
+
+    public boolean isOutgoingEmpty(E vertex) {
+        return outgoingSize(vertex) == 0;
+    }
+
+    public boolean isIncomingEmpty(E vertex) {
+        return incomingSize(vertex) == 0;
+    }
+
+    private class AllArcIterator implements ArcIterator<E, V> {
+
+        private Iterator<Entry<E, Map<E, V>>> originIterator;
+        private Iterator<Entry<E, V>> destinationIterator;
+        private E origin, nextOrigin;
+        private E destination, nextDst;
+        private V arc, nextArc;
+
+        private AllArcIterator() {
+            originIterator = graph.entrySet().iterator();
+            next();
+        }
+
+        public E getOrigin() {
+            return origin;
+        }
+
+        public E getDestination() {
+            return destination;
+        }
+
+        public boolean hasNext() {
+            return nextArc != null;
+        }
+
+        public V next() {
+            origin = nextOrigin;
+            destination = nextDst;
+            arc = nextArc;
+            if (destinationIterator == null || !destinationIterator.hasNext()) {
+                nextOrigin = null;
+                nextDst = null;
+                nextArc = null;
+
+                while (originIterator.hasNext()) {
+                    Entry<E, Map<E, V>> entry = originIterator.next();
+                    destinationIterator = entry.getValue().entrySet().iterator();
+                    if (destinationIterator.hasNext()) {
+                        nextOrigin = entry.getKey();
+                        Entry<E, V> entry1 = destinationIterator.next();
+                        nextDst = entry1.getKey();
+                        nextArc = entry1.getValue();
+                        break;
+                    }
+                }
+            }
+            else {
+                Entry<E, V> entry1 = destinationIterator.next();
+                nextDst = entry1.getKey();
+                nextArc = entry1.getValue();
+            }
+
+            return arc;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException(
+                    "Method remove() not yet implemented.");
+        }
+    }
+
+    private class OutgoingArcIterator implements ArcIterator<E, V> {
+
+        private E origin;
+        private Iterator<Entry<E, V>> dstIt;
+        private Entry<E, V> entry;
+
+        private OutgoingArcIterator(E vertex) {
+            origin = vertex;
+            dstIt = graph.get(vertex).entrySet().iterator();
+        }
+
+        public E getOrigin() {
+            return origin;
+        }
+
+        public E getDestination() {
+            if (entry == null)
+                return null;
+            return entry.getKey();
+        }
+
+        public boolean hasNext() {
+            return dstIt.hasNext();
+        }
+
+        public V next() {
+            entry = dstIt.next();
+            return entry.getValue();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException(
+                    "Method remove() not yet implemented.");
+        }
+    }
+
+    private class IncomingArcIterator implements ArcIterator<E, V> {
+
+        private E dst;
+        private E origin, nextOrigin;
+        private V arc, nextArc;
+        private Iterator<Entry<E, Map<E, V>>> graphIt;
+
+        private IncomingArcIterator(E vertex) {
+            dst = vertex;
+            graphIt = graph.entrySet().iterator();
+            next();
+        }
+
+        public E getOrigin() {
+            return origin;
+        }
+
+        public E getDestination() {
+            return dst;
+        }
+
+        public boolean hasNext() {
+            return (nextArc != null);
+        }
+
+        public V next() {
+            origin = nextOrigin;
+            arc = nextArc;
+            nextArc = null;
+            nextOrigin = null;
+            while (graphIt.hasNext()) {
+                Entry<E, Map<E, V>> entry = graphIt.next();
+                Map<E, V> destinations = entry.getValue();
+                nextArc = destinations.get(dst);
+                if (nextArc != null) {
+                    nextOrigin = entry.getKey();
+                    break;
+                }
+            }
+            return arc;
+        }
+
+        public void remove() {
+            throw new java.lang.UnsupportedOperationException(
+                    "Method remove() not yet implemented.");
+        }
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/ReversedIteration.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/ReversedIteration.java?rev=990775&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/ReversedIteration.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/ReversedIteration.java Mon Aug 30 11:52:36 2010
@@ -0,0 +1,107 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+/* ====================================================================
+ *
+ * Copyright(c) 2003, Andriy Shapochka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * 3. Neither the name of the ASHWOOD nor the
+ *    names of its contributors may be used to endorse or
+ *    promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by
+ * individuals on behalf of the ASHWOOD Project and was originally
+ * created by Andriy Shapochka.
+ *
+ */
+package org.apache.cayenne.ashwood.graph;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+public class ReversedIteration implements DigraphIteration, Serializable {
+  private DigraphIteration wrappedIteration;
+
+  public ReversedIteration(DigraphIteration wrappedIteration) {
+    this.wrappedIteration = wrappedIteration;
+  }
+  public Iterator vertexIterator() {
+    return wrappedIteration.vertexIterator();
+  }
+  public ArcIterator arcIterator() {
+    return new ReversedArcIterator(wrappedIteration.arcIterator());
+  }
+  public ArcIterator outgoingIterator(Object vertex) {
+    return new ReversedArcIterator(wrappedIteration.incomingIterator(vertex));
+  }
+  public ArcIterator incomingIterator(Object vertex) {
+    return new ReversedArcIterator(wrappedIteration.outgoingIterator(vertex));
+  }
+
+  public static class ReversedArcIterator implements ArcIterator {
+    private ArcIterator wrappedIterator;
+
+    public ReversedArcIterator(ArcIterator wrappedIterator) {
+      ReversedArcIterator.this.wrappedIterator = wrappedIterator;
+    }
+
+    public Object getOrigin() {
+      return wrappedIterator.getDestination();
+    }
+    public Object getDestination() {
+      return wrappedIterator.getOrigin();
+    }
+    public boolean hasNext() {
+      return wrappedIterator.hasNext();
+    }
+    public Object next() {
+      return wrappedIterator.next();
+    }
+    public void remove() {
+      wrappedIterator.remove();
+    }
+  }
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java?rev=990775&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ashwood/graph/StrongConnection.java Mon Aug 30 11:52:36 2010
@@ -0,0 +1,233 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+/* ====================================================================
+ *
+ * Copyright(c) 2003, Andriy Shapochka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * 3. Neither the name of the ASHWOOD nor the
+ *    names of its contributors may be used to endorse or
+ *    promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by
+ * individuals on behalf of the ASHWOOD Project and was originally
+ * created by Andriy Shapochka.
+ *
+ */
+package org.apache.cayenne.ashwood.graph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections.ArrayStack;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.functors.TruePredicate;
+
+public class StrongConnection<E> extends Algorithm<Collection<E>> {
+
+    private DigraphIteration digraph;
+    private DigraphIteration reverseDigraph;
+    private DigraphIteration filteredDigraph;
+    private DepthFirstStampSearch directDfs;
+    private DepthFirstSearch reverseDfs;
+    private Set seen = new HashSet();
+    private Iterator vertexIterator;
+    private ArrayStack dfsStack = new ArrayStack();
+    private DFSSeenVerticesPredicate reverseDFSFilter = new DFSSeenVerticesPredicate();
+
+    public StrongConnection(DigraphIteration digraph) {
+        this.digraph = digraph;
+        filteredDigraph = new FilterIteration(
+                digraph,
+                new NotSeenPredicate(),
+                TruePredicate.INSTANCE);
+        reverseDigraph = new FilterIteration(
+                new ReversedIteration(digraph),
+                reverseDFSFilter,
+                TruePredicate.INSTANCE);
+        vertexIterator = filteredDigraph.vertexIterator();
+        runDirectDFS();
+    }
+
+    public boolean hasNext() {
+        return !dfsStack.isEmpty();
+    }
+
+    public Collection<E> next() {
+        Collection component = buildStronglyConnectedComponent();
+        if (dfsStack.isEmpty())
+            runDirectDFS();
+        return component;
+    }
+
+    public Digraph contract(Digraph contractedDigraph) {
+        List components = new ArrayList();
+        CollectionUtils.addAll(components, this);
+        Map memberToComponent = new HashMap();
+        for (Iterator i = components.iterator(); i.hasNext();) {
+            Collection c = (Collection) i.next();
+            for (Iterator j = c.iterator(); j.hasNext();)
+                memberToComponent.put(j.next(), c);
+        }
+        for (Iterator i = components.iterator(); i.hasNext();) {
+            Collection origin = (Collection) i.next();
+            contractedDigraph.addVertex(origin);
+            for (Iterator j = origin.iterator(); j.hasNext();) {
+                Object member = j.next();
+                for (ArcIterator k = digraph.outgoingIterator(member); k.hasNext();) {
+                    Object arc = k.next();
+                    Object dst = k.getDestination();
+                    if (origin.contains(dst))
+                        continue;
+                    Collection destination = (Collection) memberToComponent.get(dst);
+
+                    Collection contractedArc = (Collection) contractedDigraph.getArc(
+                            origin,
+                            destination);
+                    if (contractedArc == null) {
+                        contractedArc = Collections.singletonList(arc);
+                        contractedDigraph.putArc(origin, destination, contractedArc);
+                    }
+                    else {
+                        if (contractedArc.size() == 1) {
+                            Collection tmp = contractedArc;
+                            contractedArc = new ArrayList<E>();
+                            contractedArc.addAll(tmp);
+                            contractedDigraph.putArc(origin, destination, contractedArc);
+                        }
+                        contractedArc.add(arc);
+                    }
+
+                }
+            }
+        }
+        return contractedDigraph;
+    }
+
+    private Object nextDFSRoot() {
+        /*
+         * while (vertexIterator.hasNext()) { Object vertex = vertexIterator.next(); if
+         * (!seen.contains(vertex)) return vertex; } return null;
+         */
+        return (vertexIterator.hasNext() ? vertexIterator.next() : null);
+    }
+
+    private boolean runDirectDFS() {
+        dfsStack.clear();
+        reverseDFSFilter.seenVertices.clear();
+        Object root = nextDFSRoot();
+        if (root == null)
+            return false;
+        if (directDfs == null)
+            directDfs = new DepthFirstStampSearch(filteredDigraph, root);
+        else
+            directDfs.reset(root);
+        int stamp;
+        Object vertex;
+        while (directDfs.hasNext()) {
+            vertex = directDfs.next();
+            stamp = directDfs.getStamp();
+            if (stamp == DepthFirstStampSearch.SHRINK_STAMP
+                    || stamp == DepthFirstStampSearch.LEAF_STAMP) {
+                // if (seen.add(vertex)) {
+                dfsStack.push(vertex);
+                reverseDFSFilter.seenVertices.add(vertex);
+                // }
+            }
+        }
+        seen.addAll(dfsStack);
+        return true;
+    }
+
+    private Collection buildStronglyConnectedComponent() {
+        Object root = dfsStack.pop();
+        Collection component = Collections.singletonList(root);
+        boolean singleton = true;
+        if (reverseDfs == null)
+            reverseDfs = new DepthFirstSearch(reverseDigraph, root);
+        else
+            reverseDfs.reset(root);
+        while (reverseDfs.hasNext()) {
+            Object vertex = reverseDfs.next();
+            if (vertex != root) {
+                if (singleton) {
+                    Collection tmp = component;
+                    component = new ArrayList<E>();
+                    component.addAll(tmp);
+                    singleton = false;
+                }
+                component.add(vertex);
+                dfsStack.remove(vertex);
+            }
+        }
+        reverseDFSFilter.seenVertices.removeAll(component);
+        return component;
+    }
+
+    private class DFSSeenVerticesPredicate implements Predicate {
+
+        private Set seenVertices = new HashSet();
+
+        public boolean evaluate(Object vertex) {
+            return seenVertices.contains(vertex);
+        }
+    }
+
+    private class NotSeenPredicate implements Predicate {
+
+        public boolean evaluate(Object vertex) {
+            return !seen.contains(vertex);
+        }
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java Mon Aug 30 11:52:36 2010
@@ -22,6 +22,7 @@ import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.dbsync.SchemaUpdateStrategy;
 import org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy;
+import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.configuration.AdhocObjectFactory;
 import org.apache.cayenne.configuration.ConfigurationNameMapper;
 import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
@@ -50,7 +51,6 @@ import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.event.DefaultEventManager;
 import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.map.AshwoodEntitySorter;
 import org.apache.cayenne.map.EntitySorter;
 import org.apache.cayenne.resource.ClassLoaderResourceLocator;
 import org.apache.cayenne.resource.ResourceLocator;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/AshwoodEntitySorter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/AshwoodEntitySorter.java?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/AshwoodEntitySorter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/AshwoodEntitySorter.java Mon Aug 30 11:52:36 2010
@@ -16,397 +16,21 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-
 package org.apache.cayenne.map;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.query.ObjectIdQuery;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.commons.collections.comparators.ReverseComparator;
-import org.objectstyle.ashwood.dbutil.DbUtils;
-import org.objectstyle.ashwood.dbutil.ForeignKey;
-import org.objectstyle.ashwood.dbutil.Table;
-import org.objectstyle.ashwood.graph.CollectionFactory;
-import org.objectstyle.ashwood.graph.Digraph;
-import org.objectstyle.ashwood.graph.IndegreeTopologicalSort;
-import org.objectstyle.ashwood.graph.MapDigraph;
-import org.objectstyle.ashwood.graph.StrongConnection;
 
 /**
- * Implements dependency sorting algorithms for ObjEntities, DbEntities and DataObjects.
- * Presently it works for acyclic database schemas with possible multi-reflexive tables.
- * The class uses topological sorting from the <a
- * href="http://objectstyle.org/ashwood/">Ashwood library</a>.
- * 
+ * @deprecated since 3.1 moved to "org.apache.cayenne.ashwood" package.
  * @since 1.1
  */
-public class AshwoodEntitySorter implements EntitySorter {
-
-    protected Collection<DataMap> dataMaps;
-    protected Map<DbEntity, Table> dbEntityToTableMap;
-    protected Digraph referentialDigraph;
-    protected Digraph contractedReferentialDigraph;
-    protected Map components;
-    protected Map<DbEntity, List<DbRelationship>> reflexiveDbEntities;
-
-    protected TableComparator tableComparator;
-    protected DbEntityComparator dbEntityComparator;
-    protected ObjEntityComparator objEntityComparator;
-
-    // used for lazy initialization
-    protected boolean dirty;
+public class AshwoodEntitySorter extends org.apache.cayenne.ashwood.AshwoodEntitySorter {
 
     public AshwoodEntitySorter() {
-        tableComparator = new TableComparator();
-        dbEntityComparator = new DbEntityComparator();
-        objEntityComparator = new ObjEntityComparator();
-        dirty = true;
-        dataMaps = Collections.EMPTY_LIST;
     }
 
     public AshwoodEntitySorter(Collection<DataMap> dataMaps) {
-        this();
-        setDataMaps(dataMaps);
-    }
-
-    /**
-     * Reindexes internal sorter.
-     */
-    protected synchronized void _indexSorter() {
-        if (!dirty) {
-            return;
-        }
-
-        Collection<Table> tables = new ArrayList<Table>(64);
-        dbEntityToTableMap = new HashMap<DbEntity, Table>(64);
-        reflexiveDbEntities = new HashMap<DbEntity, List<DbRelationship>>(32);
-
-        for (DataMap map : dataMaps) {
-            for (DbEntity entity : map.getDbEntities()) {
-                Table table = new Table(entity.getCatalog(), entity.getSchema(), entity
-                        .getName());
-                fillInMetadata(table, entity);
-                dbEntityToTableMap.put(entity, table);
-                tables.add(table);
-            }
-        }
-        referentialDigraph = new MapDigraph(MapDigraph.HASHMAP_FACTORY);
-        DbUtils.buildReferentialDigraph(referentialDigraph, tables);
-        StrongConnection contractor = new StrongConnection(
-                referentialDigraph,
-                CollectionFactory.ARRAYLIST_FACTORY);
-        contractedReferentialDigraph = new MapDigraph(MapDigraph.HASHMAP_FACTORY);
-        contractor.contract(
-                contractedReferentialDigraph,
-                CollectionFactory.ARRAYLIST_FACTORY);
-        IndegreeTopologicalSort sorter = new IndegreeTopologicalSort(
-                contractedReferentialDigraph);
-        components = new HashMap(contractedReferentialDigraph.order());
-        int componentIndex = 0;
-        while (sorter.hasNext()) {
-            Collection component = (Collection) sorter.next();
-            ComponentRecord rec = new ComponentRecord(componentIndex++, component);
-            for (Iterator i = component.iterator(); i.hasNext();) {
-                components.put(i.next(), rec);
-            }
-        }
-
-        // clear dirty flag
-        this.dirty = false;
-    }
-
-    /**
-     * @since 1.1
-     */
-    public synchronized void setDataMaps(Collection<DataMap> dataMaps) {
-        this.dirty = true;
-        this.dataMaps = dataMaps != null ? dataMaps : Collections.EMPTY_LIST;
-    }
-
-    public void sortDbEntities(List<DbEntity> dbEntities, boolean deleteOrder) {
-        _indexSorter();
-        Collections.sort(dbEntities, getDbEntityComparator(deleteOrder));
-    }
-
-    public void sortObjEntities(List<ObjEntity> objEntities, boolean deleteOrder) {
-        _indexSorter();
-        Collections.sort(objEntities, getObjEntityComparator(deleteOrder));
-    }
-
-    public void sortObjectsForEntity(
-            ObjEntity objEntity,
-            List objects,
-            boolean deleteOrder) {
-
-        // don't forget to index the sorter
-        _indexSorter();
-
-        DbEntity dbEntity = objEntity.getDbEntity();
-
-        // if no sorting is required
-        if (!isReflexive(dbEntity)) {
-            return;
-        }
-
-        int size = objects.size();
-        if (size == 0) {
-            return;
-        }
-
-        EntityResolver resolver = ((Persistent) objects.get(0))
-                .getObjectContext()
-                .getEntityResolver();
-        ClassDescriptor descriptor = resolver.getClassDescriptor(objEntity.getName());
-
-        List<DbRelationship> reflexiveRels = reflexiveDbEntities.get(dbEntity);
-        String[] reflexiveRelNames = new String[reflexiveRels.size()];
-        for (int i = 0; i < reflexiveRelNames.length; i++) {
-            DbRelationship dbRel = reflexiveRels.get(i);
-            ObjRelationship objRel = (dbRel != null ? objEntity
-                    .getRelationshipForDbRelationship(dbRel) : null);
-            reflexiveRelNames[i] = (objRel != null ? objRel.getName() : null);
-        }
-
-        List<Object> sorted = new ArrayList<Object>(size);
-
-        Digraph objectDependencyGraph = new MapDigraph(MapDigraph.HASHMAP_FACTORY);
-        Object[] masters = new Object[reflexiveRelNames.length];
-        for (int i = 0; i < size; i++) {
-            Persistent current = (Persistent) objects.get(i);
-            objectDependencyGraph.addVertex(current);
-            int actualMasterCount = 0;
-            for (int k = 0; k < reflexiveRelNames.length; k++) {
-                String reflexiveRelName = reflexiveRelNames[k];
-
-                if (reflexiveRelName == null) {
-                    continue;
-                }
-
-                masters[k] = descriptor.getProperty(reflexiveRelName).readProperty(
-                        current);
-
-                if (masters[k] == null) {
-                    masters[k] = findReflexiveMaster(current, (ObjRelationship) objEntity
-                            .getRelationship(reflexiveRelName), current
-                            .getObjectId()
-                            .getEntityName());
-                }
-
-                if (masters[k] != null) {
-                    actualMasterCount++;
-                }
-            }
-
-            int mastersFound = 0;
-            for (int j = 0; j < size && mastersFound < actualMasterCount; j++) {
-
-                if (i == j) {
-                    continue;
-                }
-
-                Object masterCandidate = objects.get(j);
-                for (Object master : masters) {
-                    if (masterCandidate.equals(master)) {
-                        objectDependencyGraph.putArc(
-                                masterCandidate,
-                                current,
-                                Boolean.TRUE);
-                        mastersFound++;
-                    }
-                }
-            }
-        }
-
-        IndegreeTopologicalSort sorter = new IndegreeTopologicalSort(
-                objectDependencyGraph);
-
-        while (sorter.hasNext()) {
-            Object o = sorter.next();
-            if (o == null)
-                throw new CayenneRuntimeException("Sorting objects for "
-                        + objEntity.getClassName()
-                        + " failed. Cycles found.");
-            sorted.add(o);
-        }
-
-        // since API requires sorting within the same array,
-        // simply replace all objects with objects in the right order...
-        // may come up with something cleaner later
-        objects.clear();
-        objects.addAll(sorted);
-
-        if (deleteOrder) {
-            Collections.reverse(objects);
-        }
-    }
-
-    protected void fillInMetadata(Table table, DbEntity entity) {
-        // in this case quite a dummy
-        short keySequence = 1;
-
-        for (DbRelationship candidate : entity.getRelationships()) {
-            if ((!candidate.isToMany() && !candidate.isToDependentPK())
-                    || candidate.isToMasterPK()) {
-                DbEntity target = (DbEntity) candidate.getTargetEntity();
-                boolean newReflexive = entity.equals(target);
-
-                for (DbJoin join : candidate.getJoins()) {
-                    DbAttribute targetAttribute = join.getTarget();
-                    if (targetAttribute.isPrimaryKey()) {
-                        ForeignKey fk = new ForeignKey();
-                        fk.setPkTableCatalog(target.getCatalog());
-                        fk.setPkTableSchema(target.getSchema());
-                        fk.setPkTableName(target.getName());
-                        fk.setPkColumnName(targetAttribute.getName());
-                        fk.setColumnName(join.getSourceName());
-                        fk.setKeySequence(keySequence++);
-                        table.addForeignKey(fk);
-
-                        if (newReflexive) {
-                            List<DbRelationship> reflexiveRels = reflexiveDbEntities
-                                    .get(entity);
-                            if (reflexiveRels == null) {
-                                reflexiveRels = new ArrayList<DbRelationship>(1);
-                                reflexiveDbEntities.put(entity, reflexiveRels);
-                            }
-                            reflexiveRels.add(candidate);
-                            newReflexive = false;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    protected Object findReflexiveMaster(
-            Persistent object,
-            ObjRelationship toOneRel,
-            String targetEntityName) {
-
-        DbRelationship finalRel = toOneRel.getDbRelationships().get(0);
-        ObjectContext context = object.getObjectContext();
-
-        // find committed snapshot - so we can't fetch from the context as it will return
-        // dirty snapshot; must go down the stack instead
-
-        // how do we handle this for NEW objects correctly? For now bail from the method
-        if (object.getObjectId().isTemporary()) {
-            return null;
-        }
-
-        ObjectIdQuery query = new ObjectIdQuery(
-                object.getObjectId(),
-                true,
-                ObjectIdQuery.CACHE);
-        QueryResponse response = context.getChannel().onQuery(null, query);
-        List<?> result = response.firstList();
-        if (result == null || result.size() == 0) {
-            return null;
-        }
-
-        DataRow snapshot = (DataRow) result.get(0);
-
-        ObjectId id = snapshot.createTargetObjectId(targetEntityName, finalRel);
-        return (id != null) ? context.localObject(id, null) : null;
-    }
-
-    protected Comparator getDbEntityComparator(boolean dependantFirst) {
-        Comparator c = dbEntityComparator;
-        if (dependantFirst) {
-            c = new ReverseComparator(c);
-        }
-        return c;
-    }
-
-    protected Comparator<ObjEntity> getObjEntityComparator(boolean dependantFirst) {
-        Comparator<ObjEntity> c = objEntityComparator;
-        if (dependantFirst) {
-            c = new ReverseComparator(c);
-        }
-        return c;
-    }
-
-    protected Table getTable(DbEntity dbEntity) {
-        return (dbEntity != null) ? dbEntityToTableMap.get(dbEntity) : null;
-    }
-
-    protected Table getTable(ObjEntity objEntity) {
-        return getTable(objEntity.getDbEntity());
-    }
-
-    protected boolean isReflexive(DbEntity metadata) {
-        return reflexiveDbEntities.containsKey(metadata);
-    }
-
-    private final class DbEntityComparator implements Comparator<DbEntity> {
-
-        public int compare(DbEntity o1, DbEntity o2) {
-            if (o1 == o2)
-                return 0;
-            Table t1 = getTable(o1);
-            Table t2 = getTable(o2);
-            return tableComparator.compare(t1, t2);
-        }
-    }
-
-    private final class ObjEntityComparator implements Comparator<ObjEntity> {
-
-        public int compare(ObjEntity o1, ObjEntity o2) {
-            if (o1 == o2)
-                return 0;
-            Table t1 = getTable(o1);
-            Table t2 = getTable(o2);
-            return tableComparator.compare(t1, t2);
-        }
-    }
-
-    private final class TableComparator implements Comparator<Table> {
-
-        public int compare(Table t1, Table t2) {
-            int result = 0;
-
-            if (t1 == t2)
-                return 0;
-            if (t1 == null)
-                result = -1;
-            else if (t2 == null)
-                result = 1;
-            else {
-                ComponentRecord rec1 = (ComponentRecord) components.get(t1);
-                ComponentRecord rec2 = (ComponentRecord) components.get(t2);
-                int index1 = rec1.index;
-                int index2 = rec2.index;
-                result = (index1 > index2 ? 1 : (index1 < index2 ? -1 : 0));
-                if (result != 0 && rec1.component == rec2.component)
-                    result = 0;
-            }
-            return result;
-        }
-    }
-
-    private final static class ComponentRecord {
-
-        ComponentRecord(int index, Collection<?> component) {
-            this.index = index;
-            this.component = component;
-        }
-
-        int index;
-        Collection<?> component;
+        super(dataMaps);
     }
 
 }

Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ashwood/AshwoodEntitySorterTest.java (from r990579, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/AshwoodEntitySorterTest.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ashwood/AshwoodEntitySorterTest.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ashwood/AshwoodEntitySorterTest.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/AshwoodEntitySorterTest.java&r1=990579&r2=990775&rev=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/AshwoodEntitySorterTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ashwood/AshwoodEntitySorterTest.java Mon Aug 30 11:52:36 2010
@@ -17,17 +17,17 @@
  *  under the License.
  ****************************************************************/
 
-package org.apache.cayenne.map;
+package org.apache.cayenne.ashwood;
 
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.cayenne.ashwood.AshwoodEntitySorter;
+import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.testdo.relationship.ReflexiveAndToOne;
 import org.apache.cayenne.unit.RelationshipCase;
 
-/**
- */
 public class AshwoodEntitySorterTest extends RelationshipCase {
 
     protected AshwoodEntitySorter sorter;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java Mon Aug 30 11:52:36 2010
@@ -32,6 +32,7 @@ import org.apache.cayenne.access.DataNod
 import org.apache.cayenne.access.dbsync.SchemaUpdateStrategy;
 import org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy;
 import org.apache.cayenne.access.dbsync.ThrowOnPartialOrCreateSchemaStrategy;
+import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.configuration.AdhocObjectFactory;
 import org.apache.cayenne.configuration.ConfigurationNameMapper;
 import org.apache.cayenne.configuration.ConfigurationTree;
@@ -54,7 +55,6 @@ import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.event.MockEventManager;
-import org.apache.cayenne.map.AshwoodEntitySorter;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.EntitySorter;
 import org.apache.cayenne.resource.Resource;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java Mon Aug 30 11:52:36 2010
@@ -33,8 +33,8 @@ import org.apache.cayenne.access.DataCon
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.QueryLogger;
+import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.map.AshwoodEntitySorter;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/SimpleAccessStack.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/SimpleAccessStack.java?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/SimpleAccessStack.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/SimpleAccessStack.java Mon Aug 30 11:52:36 2010
@@ -39,10 +39,10 @@ import org.apache.cayenne.access.DbGener
 import org.apache.cayenne.access.QueryLogger;
 import org.apache.cayenne.access.UnitTestDomain;
 import org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy;
+import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.event.DefaultEventManager;
-import org.apache.cayenne.map.AshwoodEntitySorter;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;

Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/ashwood.AshwoodEntitySorterTest.xml (from r990579, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/map.AshwoodEntitySorterTest.xml)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/ashwood.AshwoodEntitySorterTest.xml?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/ashwood.AshwoodEntitySorterTest.xml&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/map.AshwoodEntitySorterTest.xml&r1=990579&r2=990775&rev=990775&view=diff
==============================================================================
    (empty)

Modified: cayenne/main/trunk/framework/cayenne-server/pom.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-server/pom.xml?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-server/pom.xml (original)
+++ cayenne/main/trunk/framework/cayenne-server/pom.xml Mon Aug 30 11:52:36 2010
@@ -60,10 +60,6 @@
 			<groupId>org.apache.velocity</groupId>
 			<artifactId>velocity</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>org.objectstyle.ashwood</groupId>
-			<artifactId>ashwood</artifactId>
-		</dependency>
 	</dependencies>
 	<build>
 		<plugins>

Modified: cayenne/main/trunk/framework/cayenne-tools/pom.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-tools/pom.xml?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-tools/pom.xml (original)
+++ cayenne/main/trunk/framework/cayenne-tools/pom.xml Mon Aug 30 11:52:36 2010
@@ -79,11 +79,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.objectstyle.ashwood</groupId>
-            <artifactId>ashwood</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.cayenne.unpublished</groupId>
             <artifactId>cayenne-legal-unpublished</artifactId>
             <version>${version}</version>

Modified: cayenne/main/trunk/modeler/cayenne-modeler/pom.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/modeler/cayenne-modeler/pom.xml?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/modeler/cayenne-modeler/pom.xml (original)
+++ cayenne/main/trunk/modeler/cayenne-modeler/pom.xml Mon Aug 30 11:52:36 2010
@@ -64,11 +64,6 @@
 		</dependency>
 
 		<dependency>
-			<groupId>org.objectstyle.ashwood</groupId>
-			<artifactId>ashwood</artifactId>
-		</dependency>
-
-		<dependency>
 			<groupId>jgoodies</groupId>
 			<artifactId>forms</artifactId>
 		</dependency>

Modified: cayenne/main/trunk/pom.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/pom.xml?rev=990775&r1=990774&r2=990775&view=diff
==============================================================================
--- cayenne/main/trunk/pom.xml (original)
+++ cayenne/main/trunk/pom.xml Mon Aug 30 11:52:36 2010
@@ -231,11 +231,6 @@
 				</exclusions>
 			</dependency>
 			<dependency>
-				<groupId>org.objectstyle.ashwood</groupId>
-				<artifactId>ashwood</artifactId>
-				<version>2.0</version>
-			</dependency>
-			<dependency>
 				<groupId>commons-collections</groupId>
 				<artifactId>commons-collections</artifactId>
 				<version>3.1</version>