summaryrefslogtreecommitdiffstats
path: root/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl')
-rw-r--r--sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java644
-rw-r--r--sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java43
-rw-r--r--sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java134
-rw-r--r--sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java177
-rw-r--r--sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java33
-rw-r--r--sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java33
6 files changed, 1064 insertions, 0 deletions
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java
new file mode 100644
index 0000000000..5a243560e3
--- /dev/null
+++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImpl.java
@@ -0,0 +1,644 @@
+/*
+ * 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.implementation.guardian.impl;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMElement;
+import org.apache.tuscany.sca.contribution.service.ContributionReadException;
+import org.apache.tuscany.sca.implementation.guardian.common.InvalidRegularExpressionException;
+import org.apache.tuscany.sca.implementation.guardian.GuardianGroup;
+import org.apache.tuscany.sca.implementation.guardian.GuardianMember;
+import org.apache.tuscany.sca.implementation.guardian.common.ConcurrentExceptionOcurrenceException;
+import org.apache.tuscany.sca.implementation.guardian.common.Constants;
+import org.apache.tuscany.sca.implementation.guardian.common.Context;
+import org.apache.tuscany.sca.implementation.guardian.common.GlobalException;
+import org.apache.tuscany.sca.implementation.guardian.common.GlobalExceptionInterface;
+import org.apache.tuscany.sca.implementation.guardian.common.InvalidNodeException;
+import org.apache.tuscany.sca.implementation.guardian.common.ResolutionTreeUtils;
+import org.apache.tuscany.sca.implementation.guardian.common.SuspendException;
+import org.apache.tuscany.sca.implementation.guardian.xml.RecoveryRulesProcessor;
+import org.apache.tuscany.sca.implementation.guardian.xml.ResolutionTreesProcessor;
+
+public class GuardianGroupImpl implements GuardianGroup {
+
+ private List<GuardianMember> guardianList;
+ private InnerGuardianGroupThread innerThread;
+ private List<GlobalExceptionInterface> concurrentExList;
+ private Map<String, OMElement> resolutionTreeElements;
+ private ResolutionTreeUtils resolutionTreeUtils;
+ private Map<String, OMElement> ruleElements;
+
+ public GuardianGroupImpl(String recoveryRules, String resolutionTrees) {
+ guardianList = new LinkedList<GuardianMember>();
+ concurrentExList = new LinkedList<GlobalExceptionInterface>();
+ innerThread = new InnerGuardianGroupThread();
+ resolutionTreeUtils = new ResolutionTreeUtils();
+
+ setRecoveryRules(recoveryRules);
+ setResolutionTree(resolutionTrees);
+ }
+
+ private void setRecoveryRules(String recoveryRules) {
+ try {
+ FileInputStream fileInputStream = new FileInputStream(recoveryRules);
+ XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);
+
+ RecoveryRulesProcessor processor = new RecoveryRulesProcessor();
+ ruleElements = processor.read(xmlReader).getRuleElements();
+
+ } catch (ContributionReadException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (XMLStreamException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private void setResolutionTree(String resolutionTree) {
+
+ try {
+ FileInputStream fileInputStream = new FileInputStream(resolutionTree);
+ XMLStreamReader resolutionTreeReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);
+
+ ResolutionTreesProcessor processor = new ResolutionTreesProcessor();
+ resolutionTreeElements = processor.read(resolutionTreeReader).getResolutionTreeElements();
+
+ } catch (ContributionReadException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (XMLStreamException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public void addGuardianMember(GuardianMember guardianMember) {
+ guardianList.add(guardianMember);
+ guardianMember.setUniqueParticipantID(guardianList.size() - 1);
+ }
+
+ public boolean removeGuardianMember(GuardianMember guardianMember) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void enableContext(Context context) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void removeContext() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized void gthrow(GlobalExceptionInterface ex, List<String> participantList) {
+
+ concurrentExList.add(ex);
+
+ //Sends a message representing the exception to the other guardian members
+ SuspendException suspendEx = new SuspendException();
+ suspendEx.putSignalingParticipant(ex.getSignalingParticipants().get(0));
+
+ if (participantList == null) {
+ for (GuardianMember g : guardianList) {
+ g.gthrow(suspendEx, null);
+ }
+ } else {
+ for (GuardianMember g : guardianList) {
+ if (participantList.contains(g.getParticipantIdentifier()) ||
+ g.getParticipantIdentifier().equals(ex.getSignalingParticipants().get(0))) {
+ g.gthrow(suspendEx, null);
+ }
+ }
+ }
+
+ if (!innerThread.isRunning()) {
+ innerThread.setGlobalException(ex);
+ new Thread(innerThread).start();
+ }
+
+ }
+
+ public boolean propagate(GlobalExceptionInterface ex) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void checkExceptionStatus() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ private class InnerGuardianGroupThread implements Runnable {
+
+ private boolean isRunning;
+ private GlobalExceptionInterface ex = null;
+
+ public InnerGuardianGroupThread() {
+ isRunning = false;
+ }
+
+ public void setGlobalException(GlobalExceptionInterface ex) {
+ this.ex = ex;
+ }
+
+ public GlobalExceptionInterface getGlobalException() {
+ return ex;
+ }
+
+ public void run() {
+ isRunning = true;
+
+ if (ex != null) {
+
+ //Time window of 10 seconds just for tests
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException ex1) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1);
+ }
+
+ try {
+ applyRecoveryRules(ex);
+ } catch (ConcurrentExceptionOcurrenceException ce) {
+ applyConcurrentRecoveryRules();
+ }
+
+ //Clear the concurrent exception list
+ concurrentExList.clear();
+
+ //Set up the participant state to NORMAL
+ for (GuardianMember gm : guardianList) {
+ if (gm.getParticipantState() == SUSPENDED_PARTICIPANT_STATE) {
+ gm.setParticipantState(NORMAL_PARTICIPANT_STATE);
+ }
+ }
+ }
+ isRunning = false;
+ }
+
+ public boolean isRunning() {
+ return isRunning;
+ }
+
+ private void applyRecoveryRules(GlobalExceptionInterface ex) throws ConcurrentExceptionOcurrenceException {
+ ruleTag(ex, ruleElements.values().iterator());
+ }
+
+ private void ruleTag(GlobalExceptionInterface ex, Iterator<OMElement> ruleElements) throws ConcurrentExceptionOcurrenceException {
+ String signaledException;
+ String exceptionName;
+
+ OMElement rule;
+ while (ruleElements.hasNext()) {
+
+ rule = ruleElements.next();
+ signaledException = getAttributeValue(rule, Constants.SIGNALED_EXCEPTION);
+ exceptionName = ex.getClass().getName();
+
+ if (signaledException.equals(exceptionName)) {
+ participantExceptionTag(ex, rule.getChildElements());
+ break;
+ }
+ }
+ }
+
+ private void participantExceptionTag(GlobalExceptionInterface ex, Iterator<OMElement> participantElements) throws ConcurrentExceptionOcurrenceException {
+ String matchParticipant;
+ List<GuardianMember> gmList;
+
+ OMElement participant;
+ while (participantElements.hasNext()) {
+ participant = participantElements.next();
+
+ matchParticipant = getAttributeValue(participant, Constants.MATCH);
+ gmList = getMatchingParticipants(matchParticipant, ex);
+
+ if (!gmList.isEmpty()) {
+ throwExceptionTag(gmList, ex, participant.getChildElements());
+ }
+ }
+ }
+
+ private void throwExceptionTag(List<GuardianMember> gmList, GlobalExceptionInterface ex, Iterator<OMElement> throwExceptionElements) throws ConcurrentExceptionOcurrenceException {
+ String className;
+ String targetContextName;
+ Integer minParticipantJoined;
+ Integer maxParticipantJoined;
+
+ OMElement throwException;
+ while (throwExceptionElements.hasNext()) {
+
+ throwException = throwExceptionElements.next();
+
+ className = getAttributeValue(throwException, Constants.CLASS);
+ targetContextName = getAttributeValue(throwException, Constants.TARGET_CONTEXT);
+
+ try {
+ minParticipantJoined = Integer.parseInt(getAttributeValue(throwException, Constants.MIN_PARTICIPANT_JOINED));
+ } catch (NumberFormatException nex) {
+ minParticipantJoined = null;
+ }
+
+ try {
+ maxParticipantJoined = Integer.parseInt(getAttributeValue(throwException, Constants.MAX_PARTICIPANT_JOINED));
+ } catch (NumberFormatException nexc) {
+ maxParticipantJoined = null;
+ }
+
+ //Test the min and max joined participants condition
+ if (minParticipantJoined != null && maxParticipantJoined != null) {
+ if (!(guardianList.size() >= minParticipantJoined && guardianList.size() < maxParticipantJoined)) {
+ break;
+ }
+ } else if (minParticipantJoined != null) {
+ if (!(guardianList.size() >= minParticipantJoined)) {
+ break;
+ }
+ } else if (minParticipantJoined != null) {
+ if (!(guardianList.size() >= minParticipantJoined)) {
+ break;
+ }
+ }
+
+ //<affected_participants>
+ String affectedParticipants = affectedParticipantsTag(throwException.getChildElements());
+ int index = -1;
+
+ //Verify if the parameter is an index
+ try {
+ index = Integer.parseInt(affectedParticipants);
+ } catch (NumberFormatException nexc) {
+ index = -1;
+ }
+
+ //Create the new exception instance
+ Class exceptionClass;
+ try {
+ exceptionClass = Class.forName(className);
+
+ Context targetContext;
+ if (targetContextName.toUpperCase().equals(Context.CURRENT_CONTEXT.getName().toUpperCase())) {
+ targetContext = Context.CURRENT_CONTEXT;
+ } else if (targetContextName.toUpperCase().equals(Context.INIT_CONTEXT.getName().toUpperCase())) {
+ targetContext = Context.INIT_CONTEXT;
+ } else {
+ targetContext = new Context(targetContextName);
+ }
+ GlobalException newException = (GlobalException) exceptionClass.newInstance();
+
+ newException.setTargetContext(targetContext);
+ newException.setSignalingContext(ex.getSignalingContext());
+ newException.putSignalingParticipant(ex.getSignalingParticipants().toString());
+
+ //Check concurrent exception existence
+ if (concurrentExList.size() > 1) {
+ throw new ConcurrentExceptionOcurrenceException(concurrentExList.toString());
+ }
+
+ //Add the exception to the participants matched
+ if (index != -1) {
+ gmList.get(index).addException(newException);
+ } else if (affectedParticipants != null && affectedParticipants.length() != 0) {
+ if (affectedParticipants.toUpperCase().equals(Constants.FIRST)) {
+ gmList.get(0).addException(newException);
+ } else if (affectedParticipants.toUpperCase().equals(Constants.LAST)) {
+ gmList.get(gmList.size() - 1).addException(newException);
+ } else if (affectedParticipants.toUpperCase().equals(Constants.ALL)) {
+ for (GuardianMember gm : gmList) {
+ gm.addException(newException);
+ }
+ }
+ } else {
+ for (GuardianMember gm : gmList) {
+ gm.addException(newException);
+ }
+ }
+
+ } catch (InstantiationException ex1) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1);
+ } catch (IllegalAccessException ex1) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1);
+ } catch (ClassNotFoundException ex1) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex1);
+ }
+ }
+ }
+
+ private String affectedParticipantsTag(Iterator<OMElement> affectedParticipantElements) {
+
+ String affectedParticipantValue = null;
+
+ OMElement affectedParticipant;
+ while (affectedParticipantElements.hasNext()) {
+
+ affectedParticipant = affectedParticipantElements.next();
+ affectedParticipantValue = affectedParticipant.getText();
+ }
+
+ if (affectedParticipantValue != null && affectedParticipantValue.length() == 0) {
+ affectedParticipantValue = null;
+ }
+
+ return affectedParticipantValue;
+ }
+
+ private String getAttributeValue(OMElement element, String attributeName) {
+ OMAttribute at;
+ Iterator it = element.getAllAttributes();
+
+ while (it.hasNext()) {
+ at = (OMAttribute) it.next();
+ if (at.getLocalName().equals(attributeName)) {
+ return at.getAttributeValue();
+ }
+ }
+
+ return null;
+ }
+
+ private void applyConcurrentRecoveryRules() {
+
+ boolean concurrentExOcurrence = false;
+ List<GlobalExceptionInterface> copyConcurrentExList;
+ GlobalExceptionInterface resolvedEx;
+
+ do {
+ System.out.println("Concurrent exceptions: " + concurrentExList);
+
+ copyConcurrentExList = new LinkedList(concurrentExList);
+
+ resolvedEx = checkExceptionResolutionTrees(copyConcurrentExList, resolutionTreeElements.values().iterator());
+
+ concurrentExList.clear();
+
+ System.out.println("Resolved Exception: " + resolvedEx);
+ if (resolvedEx != null) {
+ System.out.println("List of participants: " + resolvedEx.getSignalingParticipants());
+ }
+
+ try {
+ //Process the exception list sequentially
+ if (resolvedEx == null) {
+ for (GlobalExceptionInterface ex : copyConcurrentExList) {
+ applyRecoveryRules(ex);
+ }
+ } else {
+ applyRecoveryRules(resolvedEx);
+ }
+
+ } catch (ConcurrentExceptionOcurrenceException exc) {
+ concurrentExOcurrence = true;
+ break;
+ }
+ } while (concurrentExOcurrence);
+ }
+
+ //FIXME: Need to check the exception level
+ private GlobalExceptionInterface checkExceptionResolutionTrees(List<GlobalExceptionInterface> exceptionList, Iterator resolutionTreesElements) {
+
+ OMElement tree;
+ OMElement root;
+ String exceptionLevel = null;
+ GlobalExceptionInterface resolvedEx = null;
+
+ while (resolutionTreesElements.hasNext()) {
+ tree = (OMElement) resolutionTreesElements.next();
+ exceptionLevel = tree.getAttributeValue(Constants.EXCEPTION_LEVEL_QNAME);
+
+ root = (OMElement) tree.getChildElements().next();
+ resolvedEx = checkExceptionResolutionTree(exceptionList, root);
+
+ if (resolvedEx != null) {
+ break;
+ }
+ }
+
+ return resolvedEx;
+ }
+
+ //Search for the root of the smallest subtree that contains all the concurrently signaled exceptions. If not found, return null.
+ private GlobalExceptionInterface checkExceptionResolutionTree(List<GlobalExceptionInterface> exceptionList, OMElement rootTree) {
+
+ resolutionTreeUtils.setRoot(rootTree);
+ String ex1, ex2;
+ GlobalExceptionInterface resolvedEx = null;
+
+ ex1 = exceptionList.get(0).getClass().getName();
+ for (int i = 1; i < exceptionList.size(); i++) {
+ ex2 = exceptionList.get(i).getClass().getName();
+
+ try {
+ ex1 = resolutionTreeUtils.getLowestCommonAncestor(ex1, ex2);
+ } catch (InvalidNodeException invalidNodeException) {
+ ex1 = null;
+ break;
+ }
+ }
+
+ if (ex1 != null) {
+ Class exceptionClass;
+
+ try {
+ exceptionClass = Class.forName(ex1);
+ resolvedEx = (GlobalException) exceptionClass.newInstance();
+
+ for (GlobalExceptionInterface ex : exceptionList) {
+ resolvedEx.putSignalingParticipant(ex.getSignalingParticipants().get(0));
+ }
+
+ } catch (InstantiationException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (IllegalAccessException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (ClassNotFoundException ex) {
+ Logger.getLogger(GuardianGroupImpl.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return resolvedEx;
+
+ } else {
+ return null;
+ }
+ }
+
+ private List<GuardianMember> getMatchingParticipants(String regularExpression, GlobalExceptionInterface signaledException) {
+ List<GuardianMember> matchingParticipants = new LinkedList();
+ String[] splitByComma = regularExpression.split(",");
+
+ //Invalid regular expression
+ if (splitByComma.length > 2) {
+ throw new InvalidRegularExpressionException("The comma ',' operator can only be applied for two expressions");
+ }
+
+ //There is no comma on the regular expression
+ if (splitByComma.length == 1) {
+
+ if (regularExpression.toUpperCase().equals("SIGNALER")) {
+ for (GuardianMember gm : guardianList) {
+ if (signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) {
+ matchingParticipants.add(gm);
+ }
+ }
+ } else if (regularExpression.toUpperCase().equals("!SIGNALER")) {
+ for (GuardianMember gm : guardianList) {
+ if (!signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) {
+ matchingParticipants.add(gm);
+ }
+ }
+
+ } else {
+ //Create an java regular expression
+ String re = createJavaRegularExpression(regularExpression);
+
+ for (GuardianMember gm : guardianList) {
+ if (gm.getParticipantIdentifier().matches(re)) {
+ matchingParticipants.add(gm);
+ }
+ }
+ }
+
+ } //There is comma on the regular expression
+ else {
+
+ String element;
+ int index = -1;
+ for (int i = 0; i < splitByComma.length; i++) {
+ element = splitByComma[i].toUpperCase();
+ if (element.equals("SIGNALER") || element.equals("!SIGNALER")) {
+ if (index == -1) {
+ index = i;
+ } else {
+ index = -1;
+ }
+ }
+ }
+
+ //Invalid expression
+ if (index == -1) {
+ throw new InvalidRegularExpressionException("The comma ',' requires a SIGNALER or !SIGNALER element in one side of the expression");
+ }
+
+ String re = createJavaRegularExpression(splitByComma[1 - index]);
+
+ for (GuardianMember gm : guardianList) {
+
+ //Test if the participant matches with the regular expression
+ if (gm.getParticipantIdentifier().matches(re)) {
+
+ //Test if the participant is Signaler
+ if (splitByComma[index].toUpperCase().equals("SIGNALER")) {
+
+ if (signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) {
+ matchingParticipants.add(gm);
+ }
+ } //Test if the participant is not Signaler
+ else {
+ if (!signaledException.getSignalingParticipants().contains(gm.getParticipantIdentifier())) {
+ matchingParticipants.add(gm);
+ }
+ }
+ }
+ }
+
+ }
+
+ return matchingParticipants;
+ }
+
+ /* Valid expressions: *, <Context>.*, <Context>, *.<Context>, *.<Context>.*,
+ * *.<Context>.*.<Context>.*, <REG_EXP> || <REG_EXP>
+ *
+ * Invalid expressions: *.*, **,
+ *
+ * Not supported yet: !<Context>, !<Context> || <Context>, !(<Context> || <Context>)
+ */
+ private String createJavaRegularExpression(String regularExpression) throws InvalidRegularExpressionException {
+ StringBuffer re = new StringBuffer();
+
+ String[] splitByBar = regularExpression.split("\\|\\|");
+ String[] splitByPeriod;
+
+ for (int i = 0; i < splitByBar.length; i++) {
+
+ splitByPeriod = splitByBar[i].split("\\.");
+
+ if (i > 0) {
+ re.append("|");
+ }
+
+ re.append("^");
+ for (int j = 0; j < splitByPeriod.length; j++) {
+
+ //*
+ if (splitByPeriod[j].equals("*")) {
+
+ //Validate the regular expression
+ if (j + 1 != splitByPeriod.length && splitByPeriod[j + 1].equals("*")) {
+ throw new InvalidRegularExpressionException();
+ }
+
+ //*
+ if (splitByPeriod.length == 1) {
+ re.append("(\\w+)");
+ } //*.<CONTEXT>
+
+ if (j == 0 && splitByPeriod.length != 1) {
+ re.append("(\\w+\\");
+ re.append(".)*");
+ } //<CONTEXT>.*
+ else {
+ re.append("(\\");
+ re.append(".\\w+)*");
+ }
+ } //<CONTEXT>
+ else {
+
+// //Validate the regular expression
+// if (splitedByPeriod[j].matches("^(\\*)*$")) {
+// throw new RuntimeException("Invalid name for a context");
+// }
+
+ //<CONTEXT> || <CONTEXT>.<CONTEXT>.<CONTEXT> || *.<CONTEXT>
+ if (splitByPeriod.length == 1) {
+ re.append("(\\w+\\");
+ re.append(".)*");
+ }
+
+ if (j == 0 || j - 1 == 0) {
+ re.append("(" + splitByPeriod[j] + ")");
+ } else {
+ re.append("(\\." + splitByPeriod[j] + ")");
+ }
+ }
+ }
+ re.append("$");
+ }
+ return re.toString();
+ }
+ }
+}
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java
new file mode 100644
index 0000000000..cf6b3245ce
--- /dev/null
+++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationFactoryImpl.java
@@ -0,0 +1,43 @@
+/*
+ * 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.implementation.guardian.impl;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.implementation.guardian.GuardianGroupImplementation;
+import org.apache.tuscany.sca.implementation.guardian.GuardianGroupImplementationFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+
+public class GuardianGroupImplementationFactoryImpl implements GuardianGroupImplementationFactory {
+
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+
+ public GuardianGroupImplementationFactoryImpl(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+ this.assemblyFactory = assemblyFactory;
+ this.javaFactory = javaFactory;
+ }
+
+ public GuardianGroupImplementation createGuardianGroupImplementation() {
+ return new GuardianGroupImplementationImpl(assemblyFactory, javaFactory);
+ }
+
+// public GuardianGroupImplementation createGuardianGroupImplementation() {
+// return new GuardianGroupImplementationImpl();
+// }
+}
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java
new file mode 100644
index 0000000000..7520846d55
--- /dev/null
+++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianGroupImplementationImpl.java
@@ -0,0 +1,134 @@
+/*
+ * 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.implementation.guardian.impl;
+
+import org.apache.tuscany.sca.implementation.guardian.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.axiom.om.OMElement;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+
+public class GuardianGroupImplementationImpl implements GuardianGroupImplementation {
+
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+ private List<Service> services = new ArrayList<Service>();
+ private OMElement guardianProperties;
+
+ public GuardianGroupImplementationImpl(AssemblyFactory assemblyFactory,
+ JavaInterfaceFactory javaFactory) {
+
+ this.assemblyFactory = assemblyFactory;
+ this.javaFactory = javaFactory;
+ this.guardianProperties = null;
+ }
+
+ private void introspectServices(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+
+ Service guardianService = assemblyFactory.createService();
+
+ guardianService.setName("GuardianGroup");
+
+ JavaInterface guardianInterface;
+
+ try {
+ guardianInterface = javaFactory.createJavaInterface(GuardianGroup.class);
+ } catch (InvalidInterfaceException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+
+ JavaInterfaceContract guardianInterfaceContract = javaFactory.createJavaInterfaceContract();
+
+ guardianInterfaceContract.setInterface(guardianInterface);
+
+ guardianService.setInterfaceContract(guardianInterfaceContract);
+
+ services.add(guardianService);
+ }
+
+ public void setGuardianProperties(OMElement guardianProperties) {
+ this.guardianProperties = guardianProperties;
+ }
+
+ public OMElement getGuardianProperties() {
+ return this.guardianProperties;
+ }
+
+ @Override
+ public String getURI() {
+ // The Guardian Model implementation does not have a URI
+ return null;
+ }
+
+ @Override
+ public void setURI(String arg0) {
+ // The Guardian Model implementation does not have a URI
+ }
+
+ @Override
+ public List<Service> getServices() {
+ if (services == null || services.size() == 0) {
+ introspectServices(assemblyFactory, javaFactory);
+ }
+ return services;
+ }
+
+ @Override
+ public List<Reference> getReferences() {
+ // The Guardian Model implementation does not support references
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Property> getProperties() {
+ // The sample DATA implementation does not support properties
+ return Collections.emptyList();
+ }
+
+ @Override
+ public ConstrainingType getConstrainingType() {
+ // The Guardian Model implementation does not support constrainingTypes
+ return null;
+ }
+
+ @Override
+ public void setConstrainingType(ConstrainingType arg0) {
+ // The Guardian Model implementation does not support constrainingTypes
+ }
+
+ @Override
+ public boolean isUnresolved() {
+ // The Guardian Model implementation is always resolved
+ return false;
+ }
+
+ @Override
+ public void setUnresolved(boolean arg0) {
+ // The Guardian Model implementation is always resolved
+ }
+}
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java
new file mode 100644
index 0000000000..80b9321e79
--- /dev/null
+++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/GuardianMemberImpl.java
@@ -0,0 +1,177 @@
+/*
+ * 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.implementation.guardian.impl;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Stack;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.tuscany.sca.implementation.guardian.common.GlobalExceptionInterface;
+import org.apache.tuscany.sca.implementation.guardian.GuardianGroup;
+import org.apache.tuscany.sca.implementation.guardian.GuardianMember;
+import org.apache.tuscany.sca.implementation.guardian.common.Context;
+import org.apache.tuscany.sca.implementation.guardian.common.GlobalException;
+import org.apache.tuscany.sca.implementation.guardian.common.JoinException;
+import org.apache.tuscany.sca.implementation.guardian.common.SuspendException;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Scope;
+import org.osoa.sca.annotations.Service;
+
+@Service(GuardianMember.class)
+@Scope("COMPOSITE")
+public class GuardianMemberImpl implements GuardianMember {
+
+ private int participantState;
+ private Stack<Context> contextList;
+
+ private Queue<GlobalException> exceptionQueue;
+ @Reference(name = "guardian_group", required = true)
+ public GuardianGroup guardianGroup;
+ private int id;
+ //FIXME: Review the usage of this variable
+ private boolean exceptionThrown;
+
+ public GuardianMemberImpl() {
+ contextList = new Stack<Context>();
+ contextList.add(Context.INIT_CONTEXT);
+ exceptionQueue = new LinkedList<GlobalException>();
+ participantState = GuardianGroup.NORMAL_PARTICIPANT_STATE;
+ exceptionThrown = false;
+ }
+
+ @Init
+ public void init() {
+ guardianGroup.addGuardianMember(this);
+ }
+
+ @Destroy
+ public void destroy() {
+ guardianGroup.removeGuardianMember(this);
+ }
+
+ public void addException(GlobalException ex) {
+ exceptionQueue.add(ex);
+ }
+
+ public Context getCurrentContext() {
+ return contextList.peek();
+ }
+
+
+ public void enableContext(Context context) {
+ //Update the context list with the related set of exceptions
+ contextList.push(context);
+
+ if (contextList.size() == 2) {
+ JoinException ex = new JoinException();
+ ex.setSignalingContext(context);
+ ex.putSignalingParticipant(getParticipantIdentifier());
+ gthrow(ex, null);
+ }
+
+ }
+
+ public void removeContext() {
+ if (!contextList.isEmpty()) {
+ contextList.pop();
+ }
+ }
+
+ //If participantList is null then signal to ALL participants
+ public void gthrow(GlobalExceptionInterface ex, List<String> participantList) {
+ //1)Block the participant until raise an exception
+
+ if (!(ex instanceof SuspendException)) {
+ //Set the exception's parameters
+ ex.setSignalingContext(getCurrentContext());
+ ex.putSignalingParticipant(getParticipantIdentifier());
+
+ guardianGroup.gthrow(ex, participantList);
+ exceptionThrown = true;
+ } else {
+ setParticipantState(GuardianGroup.SUSPENDED_PARTICIPANT_STATE);
+ }
+ }
+
+ public boolean propagate(GlobalExceptionInterface ex) {
+ //1)Compares the current context with the exception's target context
+ return !getCurrentContext().equals(ex.getTargetContext());
+ }
+
+ public void checkExceptionStatus() throws GlobalException {
+
+ //Blocks until the state be diferent the SUSPENDED_STATE
+ while (participantState == GuardianGroup.SUSPENDED_PARTICIPANT_STATE && exceptionThrown) {
+ System.out.println(getParticipantIdentifier() + ": I am blocked!");
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(GuardianMemberImpl.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ exceptionThrown = false;
+ System.out.println(getParticipantIdentifier() + ": I am not blocked!");
+
+ GlobalException exc;
+
+ if ((exc = exceptionQueue.peek()) == null) {
+ System.out.println(getParticipantIdentifier() + "#No exception on exception queue");
+ return;
+ }
+
+ //Check if ex.targetContext() matches the participant id
+ //Eg. ex.targetContext(): Main and participant id: Init.Main.Backup -> should thrown the exception
+ //Test if the exception should be thrown in the target context
+ for (Context c : contextList) {
+ if (exc.getTargetContext().equals(c) && (c.equals(Context.INIT_CONTEXT) || c.getExceptionList().contains(exc.getClass()))) {
+ System.out.println(getParticipantIdentifier() + "#Returning an exception");
+ exceptionQueue.poll();
+ throw exc;
+ }
+ }
+
+ return;
+ }
+
+ public String getParticipantIdentifier() {
+ //1) Return the participant identifier -> context list dot separated
+ StringBuffer participantIdentifier = new StringBuffer();
+ participantIdentifier.append(this.id);
+ for (int i = 0; i < contextList.size(); i++) {
+ participantIdentifier.append("." + contextList.get(i).getName());
+ }
+ return participantIdentifier.toString();
+ }
+
+ public void setUniqueParticipantID(int id) {
+ this.id = id;
+ }
+
+ public int getParticipantState() {
+ return participantState;
+ }
+
+ public void setParticipantState(int state) {
+ this.participantState = state;
+ }
+}
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java
new file mode 100644
index 0000000000..e2fc2f8048
--- /dev/null
+++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/RecoveryRulesImpl.java
@@ -0,0 +1,33 @@
+/*
+ * 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.implementation.guardian.impl;
+
+import org.apache.tuscany.sca.implementation.guardian.RecoveryRules;
+import java.util.Hashtable;
+import java.util.Map;
+import org.apache.axiom.om.OMElement;
+
+public class RecoveryRulesImpl implements RecoveryRules {
+
+ private Map<String, OMElement> ruleElements = new Hashtable<String, OMElement>();
+
+ public Map<String, OMElement> getRuleElements() {
+ return ruleElements;
+ }
+}
diff --git a/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java
new file mode 100644
index 0000000000..669f06b1ef
--- /dev/null
+++ b/sandbox/dougsleite/implementation-guardian/src/main/java/org/apache/tuscany/sca/implementation/guardian/impl/ResolutionTreesImpl.java
@@ -0,0 +1,33 @@
+/*
+ * 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.implementation.guardian.impl;
+
+import java.util.Hashtable;
+import java.util.Map;
+import org.apache.axiom.om.OMElement;
+import org.apache.tuscany.sca.implementation.guardian.ResolutionTrees;
+
+public class ResolutionTreesImpl implements ResolutionTrees {
+
+ private Map<String, OMElement> resolutionTreeElements = new Hashtable<String, OMElement>();
+
+ public Map<String, OMElement> getResolutionTreeElements() {
+ return resolutionTreeElements;
+ }
+}