/* * 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.ode.bpel.runtime; import org.apache.ode.bpel.o.OActivity; import org.apache.ode.bpel.o.OScope; import org.apache.ode.bpel.o.OSequence; import org.apache.ode.bpel.runtime.channels.FaultData; import org.apache.ode.bpel.runtime.channels.ParentScopeChannel; import org.apache.ode.bpel.runtime.channels.ParentScopeChannelListener; import org.apache.ode.bpel.runtime.channels.TerminationChannel; import org.apache.ode.bpel.runtime.channels.TerminationChannelListener; import org.apache.ode.jacob.SynchChannel; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.w3c.dom.Element; /** * Implementation of the BPEL <sequence> activity. */ class SEQUENCE extends ACTIVITY { private static final long serialVersionUID = 1L; private final List<OActivity> _remaining; private final Set<CompensationHandler> _compensations; SEQUENCE(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame) { this(self, scopeFrame, linkFrame, ((OSequence)self.o).sequence, CompensationHandler.emptySet()); } SEQUENCE(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame, List<OActivity> remaining, Set<CompensationHandler> compensations) { super(self, scopeFrame, linkFrame); _remaining = Collections.unmodifiableList(remaining); _compensations =Collections.unmodifiableSet(compensations); } public void run() { final ActivityInfo child = new ActivityInfo(genMonotonic(), _remaining.get(0), newChannel(TerminationChannel.class), newChannel(ParentScopeChannel.class)); instance(createChild(child, _scopeFrame, _linkFrame)); instance(new ACTIVE(child)); } private class ACTIVE extends BpelJacobRunnable { private static final long serialVersionUID = -2663862698981385732L; private ActivityInfo _child; private boolean _terminateRequested = false; ACTIVE(ActivityInfo child) { _child = child; } public void run() { object(false, new TerminationChannelListener(_self.self) { private static final long serialVersionUID = -2680515407515637639L; public void terminate() { replication(_child.self).terminate(); // Don't do any of the remaining activiites, DPE instead. ArrayList<OActivity> remaining = new ArrayList<OActivity>(_remaining); remaining.remove(0); deadPathRemaining(remaining); _terminateRequested = true; instance(ACTIVE.this); } }.or(new ParentScopeChannelListener(_child.parent) { private static final long serialVersionUID = 7195562310281985971L; public void compensate(OScope scope, SynchChannel ret) { _self.parent.compensate(scope,ret); instance(ACTIVE.this); } public void completed(FaultData faultData, Set<CompensationHandler> compensations) { HashSet<CompensationHandler> comps = new HashSet<CompensationHandler>(_compensations); comps.addAll(compensations); if (faultData != null || _terminateRequested || _remaining.size() <= 1) { deadPathRemaining(_remaining); _self.parent.completed(faultData, comps); } else /* !fault && ! terminateRequested && !remaining.isEmpty */ { ArrayList<OActivity> remaining = new ArrayList<OActivity>(_remaining); remaining.remove(0); instance(new SEQUENCE(_self, _scopeFrame, _linkFrame, remaining, comps)); } } public void cancelled() { completed(null, CompensationHandler.emptySet()); } public void failure(String reason, Element data) { completed(null, CompensationHandler.emptySet()); } })); } private void deadPathRemaining(List<OActivity> remaining) { for (Iterator<OActivity> i = remaining.iterator();i.hasNext();) dpe(i.next()); } } public String toString() { StringBuffer buf = new StringBuffer("SEQUENCE(self="); buf.append(_self); buf.append(", linkframe="); buf.append(_linkFrame); buf.append(", remaining="); buf.append(_remaining); buf.append(')'); return buf.toString(); } }