All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.logging.log4j.core.appender.rolling.action.AbstractPathAction Maven / Gradle / Ivy

There is a newer version: 3.0.0-beta2
Show newest version
/*
 * 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.logging.log4j.core.appender.rolling.action;

import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.core.lookup.StrSubstitutor;

/**
 * Abstract action for processing files that are accepted by the specified PathFilters.
 */
public abstract class AbstractPathAction extends AbstractAction {

    private final String basePathString;
    private final Set options;
    private final int maxDepth;
    private final List pathConditions;
    private final StrSubstitutor subst;

    /**
     * Creates a new AbstractPathAction that starts scanning for files to process from the specified base path.
     *
     * @param basePath base path from where to start scanning for files to process.
     * @param followSymbolicLinks whether to follow symbolic links. Default is false.
     * @param maxDepth The maxDepth parameter is the maximum number of levels of directories to visit. A value of 0
     *            means that only the starting file is visited, unless denied by the security manager. A value of
     *            MAX_VALUE may be used to indicate that all levels should be visited.
     * @param pathFilters an array of path filters (if more than one, they all need to accept a path before it is
     *            processed).
     */
    protected AbstractPathAction(final String basePath, final boolean followSymbolicLinks, final int maxDepth,
            final PathCondition[] pathFilters, final StrSubstitutor subst) {
        this.basePathString = basePath;
        this.options = followSymbolicLinks ? EnumSet.of(FileVisitOption.FOLLOW_LINKS)
                : Collections. emptySet();
        this.maxDepth = maxDepth;
        this.pathConditions = Arrays.asList(Arrays.copyOf(pathFilters, pathFilters.length));
        this.subst = subst;
    }

    @Override
    public boolean execute() throws IOException {
        return execute(createFileVisitor(getBasePath(), pathConditions));
    }

    public boolean execute(final FileVisitor visitor) throws IOException {
        final long start = System.nanoTime();
        LOGGER.debug("Starting {}", this);

        Files.walkFileTree(getBasePath(), options, maxDepth, visitor);

        final double duration = System.nanoTime() - start;
        LOGGER.debug("{} complete in {} seconds", getClass().getSimpleName(), duration / TimeUnit.SECONDS.toNanos(1));

        // TODO return (visitor.success || ignoreProcessingFailure)
        return true; // do not abort rollover even if processing failed
    }

    /**
     * Creates a new {@code FileVisitor} to pass to the {@link Files#walkFileTree(Path, Set, int, FileVisitor)}
     * method when the {@link #execute()} method is invoked.
     * 

* The visitor is responsible for processing the files it encounters that are accepted by all filters. * * @param visitorBaseDir base dir from where to start scanning for files to process * @param conditions filters that determine if a file should be processed * @return a new {@code FileVisitor} */ protected abstract FileVisitor createFileVisitor(final Path visitorBaseDir, final List conditions); /** * Returns the base path from where to start scanning for files to delete. Lookups are resolved, so if the * configuration was <Delete basePath="${sys:user.home}/abc" /> then this method returns a path * to the "abc" file or directory in the user's home directory. * * @return the base path (all lookups resolved) */ public Path getBasePath() { return Paths.get(subst.replace(getBasePathString())); } /** * Returns the base path as it was specified in the configuration. Lookups are not resolved. * * @return the base path as it was specified in the configuration */ public String getBasePathString() { return basePathString; } public StrSubstitutor getStrSubstitutor() { return subst; } /** * Returns whether to follow symbolic links or not. * * @return the options */ public Set getOptions() { return Collections.unmodifiableSet(options); } /** * Returns whether to follow symbolic links or not. * * @return whether to follow symbolic links or not */ public boolean isFollowSymbolicLinks() { return options.contains(FileVisitOption.FOLLOW_LINKS); } /** * Returns the the maximum number of directory levels to visit. * * @return the maxDepth */ public int getMaxDepth() { return maxDepth; } /** * Returns the list of PathCondition objects. * * @return the pathFilters */ public List getPathConditions() { return Collections.unmodifiableList(pathConditions); } @Override public String toString() { return getClass().getSimpleName() + "[basePath=" + getBasePath() + ", options=" + options + ", maxDepth=" + maxDepth + ", conditions=" + pathConditions + "]"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy