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]