/* * Copyright 2013, 2014 Deutsche Nationalbibliothek * * Licensed 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.culturegraph.mf.flux.parser; import java.util.ArrayList; import java.util.Deque; import java.util.LinkedList; import java.util.List; import org.culturegraph.mf.flux.FluxParseException; import org.culturegraph.mf.framework.LifeCycle; import org.culturegraph.mf.framework.ObjectReceiver; import org.culturegraph.mf.framework.Receiver; import org.culturegraph.mf.framework.Sender; import org.culturegraph.mf.framework.Tee; import org.culturegraph.mf.io.StdInOpener; /** * @author Markus Michael Geipel * */ final class Flow { private final Deque<Tee<?>> teeStack = new LinkedList<Tee<?>>(); private final Deque<List<LifeCycle>> looseEndsStack = new LinkedList<List<LifeCycle>>(); private LifeCycle element; private ObjectReceiver<? extends Object> start; private boolean joinLooseEnds; @SuppressWarnings({ "unchecked", "rawtypes" }) public void addElement(final Receiver nextElement) { if(element==null){ setStart((ObjectReceiver<? extends Object>) nextElement); return; } if (element instanceof Sender) { final Sender sender = (Sender) element; if (joinLooseEnds) { teeStack.pop(); for (final LifeCycle looseEnd : looseEndsStack.pop()) { if (looseEnd instanceof Tee) { ((Tee) looseEnd).addReceiver(nextElement); } else { ((Sender) looseEnd).setReceiver(nextElement); } } joinLooseEnds = false; } else { if (sender instanceof Tee) { ((Tee) sender).addReceiver(nextElement); } else { sender.setReceiver(nextElement); } } } else { throw new FluxParseException(element.getClass().getCanonicalName() + "is not a sender"); } element = nextElement; } public void startTee() { if (element instanceof Tee) { final Tee<?> tee = (Tee<?>) element; teeStack.push(tee); looseEndsStack.push(new ArrayList<LifeCycle>()); } else { throw new FluxParseException("Flow cannot be split without a tee-element."); } } public void endTee() { joinLooseEnds = true; } public void endSubFlow() { looseEndsStack.peek().add(element); element = teeStack.peek(); } private void setStart(final ObjectReceiver<? extends Object> start){ this.start = start; element = start; } public void setStringStart(final String string) { setStart(new StringSender(string)); } public void setStdInStart() { setStart(new StdInOpener()); } public void start() { start.process(null); } public void close() { start.closeStream(); } public Receiver getFirst() { return start; } }