/* * 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.policy.guardianExceptionHandling; 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.apache.tuscany.sca.invocation.Message; public class GuardianMemberImpl implements GuardianMember { private int participantState; private Stack contextList; private Queue exceptionQueue; private String id; //FIXME: Review the usage of this variable private boolean exceptionThrown; private Message msg; private GuardianExceptionHandlingPolicyInterceptor interceptor; protected GuardianMemberImpl(String componentName, Message msg, GuardianExceptionHandlingPolicyInterceptor interceptor) { contextList = new Stack(); contextList.add(Context.INIT_CONTEXT); exceptionQueue = new LinkedList(); participantState = GuardianGroup.NORMAL_PARTICIPANT_STATE; exceptionThrown = false; this.id = componentName; this.msg = msg; this.interceptor = interceptor; } public void setGuardianExceptionHandlingPolicyInterceptor(GuardianExceptionHandlingPolicyInterceptor interceptor) { this.interceptor = interceptor; } public GuardianExceptionHandlingPolicyInterceptor getGuardianExceptionHandlingPolicyInterceptor() { return this.interceptor; } public void setMessage(Message msg) { this.msg = msg; } public Message getMessage() { return this.msg; } 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 if (contextList.size() == 1) { contextList.push(context); JoinException ex = new JoinException(); ex.setSignalingContext(context); ex.putSignalingParticipant(getParticipantIdentifier()); gthrow(ex, null); } else { contextList.push(context); } } public Context removeContext() { // if (contextList.size() > 1) { // return contextList.pop(); // } return contextList.pop(); } //If participantList is null then signal to ALL participants public void gthrow(GlobalExceptionInterface ex, List participantList) { //1)Block the participant until raise an exception if (!(ex instanceof SuspendException)) { //Set the exception's parameters ex.setSignalingContext(getCurrentContext()); ex.putSignalingParticipant(getParticipantIdentifier()); //Prepare the parameters Object[] params = {ex, participantList}; msg.setBody(params); interceptor.invokeGuardianGroupOperation("gthrow", msg); //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 int getParticipantState() { return participantState; } public void setParticipantState(int state) { this.participantState = state; } }