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;
018
019import java.io.Serializable;
020import java.util.HashMap;
021import java.util.Map;
022import java.util.concurrent.TimeUnit;
023
024import org.apache.logging.log4j.core.Filter;
025import org.apache.logging.log4j.core.Layout;
026import org.apache.logging.log4j.core.config.Property;
027import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
028import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
029import org.apache.logging.log4j.core.net.Advertiser;
030
031/**
032 * Abstract File Appender.
033 */
034public abstract class AbstractFileAppender<M extends OutputStreamManager> extends AbstractOutputStreamAppender<M> {
035
036    /**
037     * Builds FileAppender instances.
038     *
039     * @param <B>
040     *            The type to build
041     */
042    public abstract static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B> {
043
044        @PluginBuilderAttribute
045        @Required
046        private String fileName;
047
048        @PluginBuilderAttribute
049        private boolean append = true;
050
051        @PluginBuilderAttribute
052        private boolean locking;
053
054        @PluginBuilderAttribute
055        private boolean advertise;
056
057        @PluginBuilderAttribute
058        private String advertiseUri;
059
060        @PluginBuilderAttribute
061        private boolean createOnDemand;
062
063        @PluginBuilderAttribute
064        private String filePermissions;
065
066        @PluginBuilderAttribute
067        private String fileOwner;
068
069        @PluginBuilderAttribute
070        private String fileGroup;
071
072        public String getAdvertiseUri() {
073            return advertiseUri;
074        }
075
076        public String getFileName() {
077            return fileName;
078        }
079
080        public boolean isAdvertise() {
081            return advertise;
082        }
083
084        public boolean isAppend() {
085            return append;
086        }
087
088        public boolean isCreateOnDemand() {
089            return createOnDemand;
090        }
091
092        public boolean isLocking() {
093            return locking;
094        }
095
096        public String getFilePermissions() {
097            return filePermissions;
098        }
099
100        public String getFileOwner() {
101            return fileOwner;
102        }
103
104        public String getFileGroup() {
105            return fileGroup;
106        }
107
108        public B withAdvertise(final boolean advertise) {
109            this.advertise = advertise;
110            return asBuilder();
111        }
112
113        public B withAdvertiseUri(final String advertiseUri) {
114            this.advertiseUri = advertiseUri;
115            return asBuilder();
116        }
117
118        public B withAppend(final boolean append) {
119            this.append = append;
120            return asBuilder();
121        }
122
123        public B withFileName(final String fileName) {
124            this.fileName = fileName;
125            return asBuilder();
126        }
127
128        public B withCreateOnDemand(final boolean createOnDemand) {
129            this.createOnDemand = createOnDemand;
130            return asBuilder();
131        }
132
133        public B withLocking(final boolean locking) {
134            this.locking = locking;
135            return asBuilder();
136        }
137
138        public B withFilePermissions(final String filePermissions) {
139            this.filePermissions = filePermissions;
140            return asBuilder();
141        }
142
143        public B withFileOwner(final String fileOwner) {
144            this.fileOwner = fileOwner;
145            return asBuilder();
146        }
147
148        public B withFileGroup(final String fileGroup) {
149            this.fileGroup = fileGroup;
150            return asBuilder();
151        }
152
153    }
154
155    private final String fileName;
156
157    private final Advertiser advertiser;
158
159    private final Object advertisement;
160
161    private AbstractFileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
162            final M manager, final String filename, final boolean ignoreExceptions,
163            final boolean immediateFlush, final Advertiser advertiser, final Property[] properties) {
164
165        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
166        if (advertiser != null) {
167            final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
168            configuration.putAll(manager.getContentFormat());
169            configuration.put("contentType", layout.getContentType());
170            configuration.put("name", name);
171            advertisement = advertiser.advertise(configuration);
172        } else {
173            advertisement = null;
174        }
175        this.fileName = filename;
176        this.advertiser = advertiser;
177    }
178
179    /**
180     * Returns the file name this appender is associated with.
181     * @return The File name.
182     */
183    public String getFileName() {
184        return this.fileName;
185    }
186
187    @Override
188    public boolean stop(final long timeout, final TimeUnit timeUnit) {
189        setStopping();
190        super.stop(timeout, timeUnit, false);
191        if (advertiser != null) {
192            advertiser.unadvertise(advertisement);
193        }
194        setStopped();
195        return true;
196    }
197}