Author: rfeng
Date: Wed Feb 20 21:19:37 2008
New Revision: 629693

URL: http://svn.apache.org/viewvc?rev=629693&view=rev
Log:
Add the seed code for phase-based interceptor ordering

Added:
    
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java
   (with props)
    
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java
   (with props)
    
incubator/tuscany/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.invocation.PhaseManager
    
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/
    
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java
   (with props)
Modified:
    
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceDiscovery.java

Modified: 
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceDiscovery.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceDiscovery.java?rev=629693&r1=629692&r2=629693&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceDiscovery.java
 (original)
+++ 
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceDiscovery.java
 Wed Feb 20 21:19:37 2008
@@ -167,15 +167,25 @@
      */
     private Map<String, String> parseServiceDeclaration(String declaration) {
         Map<String, String> attributes = new HashMap<String, String>();
+        int index = declaration.indexOf(';');
+        if (index != -1) {
+            attributes.put("class", declaration.substring(0, index).trim());
+            declaration = declaration.substring(index);
+        } else {
+            int j = declaration.indexOf('=');
+            if (j == -1) {
+                attributes.put("class", declaration.trim());
+                return attributes;
+            } else {
+                declaration = ";" + declaration;
+            }
+        }
         StringTokenizer tokens = new StringTokenizer(declaration);
-        String className = tokens.nextToken(";");
-        if (className != null)
-            attributes.put("class", className);
         for (; tokens.hasMoreTokens();) {
-            String key = tokens.nextToken("=").substring(1);
+            String key = tokens.nextToken("=").substring(1).trim();
             if (key == null)
                 break;
-            String value = tokens.nextToken(",").substring(1);
+            String value = tokens.nextToken(",").substring(1).trim();
             if (value == null)
                 break;
             attributes.put(key, value);

Added: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java?rev=629693&view=auto
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java
 (added)
+++ 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java
 Wed Feb 20 21:19:37 2008
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.tuscany.sca.core.invocation;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.contribution.util.ServiceDeclaration;
+import org.apache.tuscany.sca.contribution.util.ServiceDiscovery;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PhaseManager {
+    private static final Logger log = 
Logger.getLogger(PhaseManager.class.getName());
+
+    public static final String STAGE_REFERENCE = "reference";
+    public static final String STAGE_SERVICE = "service";
+    public static final String STAGE_IMPLEMENTATION = "implementation";
+    private static final String[] STAGES = new String[] {STAGE_REFERENCE, 
STAGE_SERVICE, STAGE_IMPLEMENTATION};
+
+    private Map<String, Stage> stages;
+
+    public class Stage {
+        private String name;
+        private PhaseSorter<String> sorter = new PhaseSorter<String>();
+        private Set<String> firstSet = new HashSet<String>();
+        private Set<String> lastSet = new HashSet<String>();
+        private List<String> phases = new ArrayList<String>();
+
+        public Stage(String name) {
+            super();
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public PhaseSorter<String> getSorter() {
+            return sorter;
+        }
+
+        public Set<String> getFirstSet() {
+            return firstSet;
+        }
+
+        public Set<String> getLastSet() {
+            return lastSet;
+        }
+
+        public List<String> getPhases() {
+            return phases;
+        }
+
+        public String toString() {
+            return name + phases;
+        }
+    }
+
+    public PhaseManager() {
+    }
+
+    public static void main(String[] args) {
+        System.out.println(new PhaseManager().getStages());
+    }
+
+    public List<String> getPhases(String stage) {
+        Stage s = getStages().get(stage);
+        return s == null ? null : s.getPhases();
+    }
+
+    public synchronized Map<String, Stage> getStages() {
+        if (stages != null) {
+            return stages;
+        }
+        stages = new HashMap<String, Stage>();
+        for (String s : STAGES) {
+            stages.put(s, new Stage(s));
+        }
+        Set<ServiceDeclaration> services;
+        try {
+            services = 
ServiceDiscovery.getInstance().getServiceDeclarations(PhaseManager.class);
+        } catch (IOException e) {
+            throw new ServiceRuntimeException(e);
+        }
+
+        for (ServiceDeclaration d : services) {
+            if (log.isLoggable(Level.FINE)) {
+                log.fine(d.getResource() + ": " + d.getAttributes());
+            }
+            String name = d.getAttributes().get("name");
+            if (name == null) {
+                throw new ServiceRuntimeException("Required attribute 'name' 
is missing.");
+            }
+            String stageName = d.getAttributes().get("stage");
+            if (stageName == null) {
+                throw new ServiceRuntimeException("Required attribute 'stage' 
is missing.");
+            }
+            Stage stage = stages.get(stageName);
+            if (stage == null) {
+                throw new ServiceRuntimeException("Invalid stage: " + stage);
+            }
+            PhaseSorter<String> graph = stage.getSorter();
+            Set<String> firstSet = stage.getFirstSet(), lastSet = 
stage.getLastSet();
+
+            String before = d.getAttributes().get("before");
+            String after = d.getAttributes().get("after");
+            if (before != null) {
+                StringTokenizer tokenizer = new StringTokenizer(before);
+                while (tokenizer.hasMoreTokens()) {
+                    String p = tokenizer.nextToken();
+                    if (!"*".equals(p)) {
+                        graph.addEdge(name, p);
+                    } else {
+                        firstSet.add(name);
+                    }
+                }
+            }
+            if (after != null) {
+                StringTokenizer tokenizer = new StringTokenizer(after);
+                while (tokenizer.hasMoreTokens()) {
+                    String p = tokenizer.nextToken();
+                    if (!"*".equals(p)) {
+                        graph.addEdge(p, name);
+                    } else {
+                        lastSet.add(name);
+                    }
+                }
+            }
+            graph.addVertext(name);
+            for (String s : firstSet) {
+                for (String v : new 
HashSet<String>(graph.getVertices().keySet())) {
+                    if (!v.equals(s)) {
+                        graph.addEdge(s, v);
+                    }
+                }
+            }
+            for (String s : lastSet) {
+                for (String v : new 
HashSet<String>(graph.getVertices().keySet())) {
+                    if (!v.equals(s)) {
+                        graph.addEdge(v, s);
+                    }
+                }
+            }
+
+        }
+
+        for (Stage s : stages.values()) {
+            List<String> phases = s.getSorter().topologicalSort(false);
+            s.getPhases().clear();
+            s.getPhases().addAll(phases);
+        }
+        if (log.isLoggable(Level.FINE)) {
+            log.fine("Stages: " + stages);
+        }
+        return stages;
+    }
+
+}

Propchange: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseManager.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java?rev=629693&view=auto
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java
 (added)
+++ 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java
 Wed Feb 20 21:19:37 2008
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Directed, weighted graph
+ * 
+ * @param <V> The type of vertex object
+ * @param <E> The type of edge object
+ */
+public class PhaseSorter<V> implements Cloneable {
+    private final Map<V, Vertex> vertices = new HashMap<V, Vertex>();
+
+    /**
+     * Vertex of a graph
+     */
+    public final class Vertex {
+        private V value;
+
+        // TODO: Do we want to support multiple edges for a vertex pair? If so,
+        // we should use a List instead of Map
+        private Map<Vertex, Edge> outEdges = new HashMap<Vertex, Edge>();
+        private Map<Vertex, Edge> inEdges = new HashMap<Vertex, Edge>();
+
+        private Vertex(V value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return "(" + value + ")";
+        }
+
+        public V getValue() {
+            return value;
+        }
+
+        public Map<Vertex, Edge> getOutEdges() {
+            return outEdges;
+        }
+
+        public Map<Vertex, Edge> getInEdges() {
+            return inEdges;
+        }
+
+    }
+
+    /**
+     * An Edge connects two vertices in one direction
+     */
+    public final class Edge {
+        private Vertex sourceVertex;
+
+        private Vertex targetVertex;
+
+        public Edge(Vertex source, Vertex target) {
+            this.sourceVertex = source;
+            this.targetVertex = target;
+        }
+
+        @Override
+        public String toString() {
+            return sourceVertex + "->" + targetVertex;
+        }
+
+        public Vertex getTargetVertex() {
+            return targetVertex;
+        }
+
+        public void setTargetVertex(Vertex vertex) {
+            this.targetVertex = vertex;
+        }
+
+        public Vertex getSourceVertex() {
+            return sourceVertex;
+        }
+
+        public void setSourceVertex(Vertex sourceVertex) {
+            this.sourceVertex = sourceVertex;
+        }
+    }
+
+    public void addEdge(V source, V target) {
+        Vertex s = getVertex(source);
+        if (s == null) {
+            s = new Vertex(source);
+            vertices.put(source, s);
+        }
+        Vertex t = getVertex(target);
+        if (t == null) {
+            t = new Vertex(target);
+            vertices.put(target, t);
+        }
+        Edge edge = new Edge(s, t);
+        s.outEdges.put(t, edge);
+        t.inEdges.put(s, edge);
+    }
+
+    public void addVertext(V source) {
+        Vertex s = getVertex(source);
+        if (s == null) {
+            s = new Vertex(source);
+            vertices.put(source, s);
+        }
+    }
+
+    public Vertex getVertex(V source) {
+        Vertex s = vertices.get(source);
+        return s;
+    }
+
+    public boolean removeEdge(V source, V target) {
+        Vertex s = getVertex(source);
+        if (s == null) {
+            return false;
+        }
+
+        Vertex t = getVertex(target);
+        if (t == null) {
+            return false;
+        }
+
+        return s.outEdges.remove(t) != null && t.inEdges.remove(s) != null;
+
+    }
+
+    public void removeEdge(Edge edge) {
+        edge.sourceVertex.outEdges.remove(edge.targetVertex);
+        edge.targetVertex.inEdges.remove(edge.sourceVertex);
+    }
+
+    public void removeVertex(Vertex vertex) {
+        vertices.remove(vertex.getValue());
+        for (Edge e : new ArrayList<Edge>(vertex.outEdges.values())) {
+            removeEdge(e);
+        }
+        for (Edge e : new ArrayList<Edge>(vertex.inEdges.values())) {
+            removeEdge(e);
+        }
+    }
+
+    public Edge getEdge(Vertex source, Vertex target) {
+        return source.outEdges.get(target);
+    }
+
+    public Edge getEdge(V source, V target) {
+        Vertex sv = getVertex(source);
+        if (sv == null) {
+            return null;
+        }
+        Vertex tv = getVertex(target);
+        if (tv == null) {
+            return null;
+        }
+        return getEdge(getVertex(source), getVertex(target));
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        for (Vertex v : vertices.values()) {
+            sb.append(v.outEdges.values()).append("\n");
+        }
+        return sb.toString();
+    }
+
+    public Map<V, Vertex> getVertices() {
+        return vertices;
+    }
+
+    public void addGraph(PhaseSorter<V> otherGraph) {
+        for (Vertex v : otherGraph.vertices.values()) {
+            for (Edge e : v.outEdges.values()) {
+                addEdge(e.sourceVertex.value, e.targetVertex.value);
+            }
+        }
+    }
+
+    private Vertex getFirst() {
+        for (Vertex v : vertices.values()) {
+            if (v.inEdges.isEmpty()) {
+                return v;
+            }
+        }
+        if (!vertices.isEmpty()) {
+            throw new IllegalArgumentException("Circular ordering has been 
detected: " + toString());
+        } else {
+            return null;
+        }
+    }
+
+    public List<V> topologicalSort(boolean readOnly) {
+        PhaseSorter<V> graph = (!readOnly) ? this : (PhaseSorter<V>)clone();
+        List<V> list = new ArrayList<V>();
+        while (true) {
+            Vertex v = graph.getFirst();
+            if (v == null) {
+                break;
+            }
+            list.add(v.getValue());
+            graph.removeVertex(v);
+        }
+
+        return list;
+    }
+
+    @Override
+    public Object clone() {
+        PhaseSorter<V> copy = new PhaseSorter<V>();
+        copy.addGraph(this);
+        return copy;
+    }
+}

Propchange: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/PhaseSorter.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
incubator/tuscany/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.invocation.PhaseManager
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.invocation.PhaseManager?rev=629693&view=auto
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.invocation.PhaseManager
 (added)
+++ 
incubator/tuscany/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.invocation.PhaseManager
 Wed Feb 20 21:19:37 2008
@@ -0,0 +1,4 @@
+name=implementation, stage=implementation, after=*
+name=reference, stage=reference, before=*
+name=service, stage=service
+name=implementation.transaction, stage=implementation, before=implementation
\ No newline at end of file

Added: 
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java?rev=629693&view=auto
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java
 (added)
+++ 
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java
 Wed Feb 20 21:19:37 2008
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class PhaseSorterTestCase extends TestCase {
+    private PhaseSorter<String> graph;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        graph = new PhaseSorter<String>();
+    }
+
+    public void testSort() {
+        graph.addEdge("a", "b");
+        graph.addEdge("a", "c");
+        graph.addEdge("c", "d");
+        graph.addEdge("b", "c");
+        List<String> order = graph.topologicalSort(true);
+        assertEquals(Arrays.asList("a", "b", "c", "d"), order);
+        assertTrue(!graph.getVertices().isEmpty());
+
+        graph.addEdge("d", "a");
+        try {
+            order = graph.topologicalSort(true);
+            assertTrue("Should have failed", false);
+        } catch (IllegalArgumentException e) {
+            assertTrue(true);
+        }
+
+        graph.removeEdge("d", "a");
+        order = graph.topologicalSort(false);
+        assertEquals(Arrays.asList("a", "b", "c", "d"), order);
+        assertTrue(graph.getVertices().isEmpty());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+}

Propchange: 
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/tuscany/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/PhaseSorterTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to