001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.core.appender.rolling.action;
018
019import java.io.IOException;
020import java.util.Arrays;
021import java.util.List;
022
023
024/**
025 * A group of Actions to be executed in sequence.
026 */
027public class CompositeAction extends AbstractAction {
028
029    /**
030     * Actions to perform.
031     */
032    private final Action[] actions;
033
034    /**
035     * Stop on error.
036     */
037    private final boolean stopOnError;
038
039    /**
040     * Construct a new composite action.
041     *
042     * @param actions     list of actions, may not be null.
043     * @param stopOnError if true, stop on the first false return value or exception.
044     */
045    public CompositeAction(final List<Action> actions,
046                           final boolean stopOnError) {
047        this.actions = new Action[actions.size()];
048        actions.toArray(this.actions);
049        this.stopOnError = stopOnError;
050    }
051
052    /**
053     * {@inheritDoc}
054     */
055    @Override
056    public void run() {
057        try {
058            execute();
059        } catch (final IOException ex) {
060            LOGGER.warn("Exception during file rollover.", ex);
061        }
062    }
063
064    /**
065     * Execute sequence of actions.
066     *
067     * @return true if all actions were successful.
068     * @throws IOException on IO error.
069     */
070    @Override
071    public boolean execute() throws IOException {
072        if (stopOnError) {
073            for (final Action action : actions) {
074                if (!action.execute()) {
075                    return false;
076                }
077            }
078
079            return true;
080        }
081        boolean status = true;
082        IOException exception = null;
083
084        for (final Action action : actions) {
085            try {
086                status &= action.execute();
087            } catch (final IOException ex) {
088                status = false;
089
090                if (exception == null) {
091                    exception = ex;
092                }
093            }
094        }
095
096        if (exception != null) {
097            throw exception;
098        }
099
100        return status;
101    }
102
103    @Override
104    public String toString() {
105        return CompositeAction.class.getSimpleName() + Arrays.toString(actions);
106    }
107
108    public Action[] getActions() {
109        return actions;
110    }
111
112    public boolean isStopOnError() {
113        return stopOnError;
114    }
115}