/* * Copyright 2007 T-Rank AS * * 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 no.trank.openpipe.api; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import no.trank.openpipe.api.document.Document; /** * @version $Revision$ */ public class BaseSubPipeline implements SubPipeline { private static final Logger log = LoggerFactory.getLogger(BaseSubPipeline.class); private final List<PipelineStep> preparedSteps = new ArrayList<PipelineStep>(); private List<? extends PipelineStep> pipelineSteps; public BaseSubPipeline() { } public BaseSubPipeline(List<? extends PipelineStep> pipelineSteps) { setPipelineSteps(pipelineSteps); } @Override public List<? extends PipelineStep> getPipelineSteps() { return pipelineSteps; } @Override public void setPipelineSteps(List<? extends PipelineStep> pipelineSteps) { this.pipelineSteps = pipelineSteps; } @Override public boolean prepare() throws PipelineException { preparedSteps.clear(); for (PipelineStep step : getPipelineSteps()) { try { step.prepare(); log.info("Prepared {} {}", step.getName(), step.getRevision().replace('$', ' ').trim()); preparedSteps.add(step); } catch (PipelineException e) { e.setPipelineStepNameIfNull(step.getName()); throw e; } catch (RuntimeException e) { throw new PipelineException(e, step.getName()); } } return true; } @Override public void finish(boolean success) throws PipelineException { final MultiPipelineException exception = finish(preparedSteps, success); if (exception != null) { throw exception; } } public static MultiPipelineException finish(Collection<? extends Finishable> steps, boolean success) { MultiPipelineException pipelineException = null; for (Finishable step : steps) { try { step.finish(success); } catch (MultiPipelineException e) { if (pipelineException == null) { pipelineException = e; } else { pipelineException.add(e.getCause()); } } catch (PipelineException e) { if (pipelineException == null) { pipelineException = new MultiPipelineException(); } pipelineException.add(e); } catch (RuntimeException e) { if (pipelineException == null) { pipelineException = new MultiPipelineException(); } pipelineException.add(new PipelineException(e)); } } steps.clear(); return pipelineException; } @Override public PipelineStatusCode executeSteps(Document document) throws PipelineException { PipelineStatusCode pipelineStatusCode = PipelineStatusCode.CONTINUE; for (PipelineStep pipelineStep : preparedSteps) { final PipelineStepStatusCode stepStatusCode; try { PipelineStepStatus status = executeStep(document, pipelineStep); if (status == null) { throw new PipelineException("null status received", pipelineStep.getName()); } stepStatusCode = status.getStatusCode(); if (stepStatusCode.hasSubPipeline()) { pipelineStatusCode = status.getSubPipeline().executeSteps(document); } else { pipelineStatusCode = stepStatusCode.toPipelineStatusCode(); } if (stepStatusCode.isDone()) { return stepStatusCode.toPipelineStatusCode(); } } catch (PipelineException e) { e.setPipelineStepNameIfNull(pipelineStep.getName()); throw e; } catch (RuntimeException e) { throw new PipelineException(e, pipelineStep.getName()); } } return pipelineStatusCode; } protected PipelineStepStatus executeStep(Document document, PipelineStep pipelineStep) throws PipelineException { final String infoString; final long start; final boolean debug = log.isDebugEnabled(); if (debug) { infoString = pipelineStep.getName() + " document operation: " + document.getOperation(); log.debug("Running {}", infoString); start = System.currentTimeMillis(); } else { infoString = null; start = 0; } final PipelineStepStatus status = pipelineStep.execute(document); if (debug) { log.debug("Execute {} took {} millis", infoString, System.currentTimeMillis() - start); } return status; } }