JAL-3048 test updated for AlignExportSettings changes
[jalview.git] / srcjar / org / apache / log4j / varia / ExternallyRolledFileAppender.java
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * 
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.apache.log4j.varia;
19
20 import java.io.DataInputStream;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.net.ServerSocket;
25 import java.net.Socket;
26
27 import org.apache.log4j.RollingFileAppender;
28 import org.apache.log4j.helpers.LogLog;
29
30 /**
31    This appender listens on a socket on the port specified by the
32    <b>Port</b> property for a "RollOver" message. When such a message
33    is received, the underlying log file is rolled over and an
34    acknowledgment message is sent back to the process initiating the
35    roll over.
36
37    <p>This method of triggering roll over has the advantage of being
38    operating system independent, fast and reliable.
39
40    <p>A simple application {@link Roller} is provided to initiate the
41    roll over.
42
43    <p>Note that the initiator is not authenticated. Anyone can trigger
44    a rollover. In production environments, it is recommended that you
45    add some form of protection to prevent undesired rollovers.
46
47
48    @author Ceki G&uuml;lc&uuml;
49    @since version 0.9.0 */
50 public class ExternallyRolledFileAppender extends RollingFileAppender {
51
52   /**
53      The string constant sent to initiate a roll over.   Current value of
54      this string constant is <b>RollOver</b>.
55   */
56   static final public String ROLL_OVER = "RollOver";
57
58   /**
59      The string constant sent to acknowledge a roll over.   Current value of
60       this string constant is <b>OK</b>.
61   */
62   static final public String OK = "OK";
63
64   int port = 0;
65   HUP hup;
66
67   /**
68      The default constructor does nothing but calls its super-class
69      constructor.  */
70   public
71   ExternallyRolledFileAppender() {
72   }
73
74   /**
75      The <b>Port</b> [roperty is used for setting the port for
76      listening to external roll over messages.
77   */
78   public
79   void setPort(int port) {
80     this.port = port;
81   }
82
83   /**
84      Returns value of the <b>Port</b> option.
85    */
86   public
87   int getPort() {
88     return port;
89   }
90
91   /**
92      Start listening on the port specified by a preceding call to
93      {@link #setPort}.  */
94   public
95   void activateOptions() {
96     super.activateOptions();
97     if(port != 0) {
98       if(hup != null) {
99         hup.interrupt();
100       }
101       hup = new HUP(this, port);
102       hup.setDaemon(true);
103       hup.start();
104     }
105   }
106 }
107
108
109 class HUP extends Thread {
110
111   int port;
112   ExternallyRolledFileAppender er;
113
114   HUP(ExternallyRolledFileAppender er, int port) {
115     this.er = er;
116     this.port = port;
117   }
118
119   public
120   void run() {
121     while(!isInterrupted()) {
122       try {
123         ServerSocket serverSocket = new ServerSocket(port);
124         while(true) {
125           Socket socket = serverSocket.accept();
126           LogLog.debug("Connected to client at " + socket.getInetAddress());
127           new Thread(new HUPNode(socket, er), "ExternallyRolledFileAppender-HUP").start();
128         }
129       } catch(InterruptedIOException e) {
130         Thread.currentThread().interrupt();
131             e.printStackTrace();
132       } catch(IOException e) {
133             e.printStackTrace();
134       } catch(RuntimeException e) {
135             e.printStackTrace();
136       }
137     }
138   }
139 }
140
141 class HUPNode implements Runnable {
142
143   Socket socket;
144   DataInputStream dis;
145   DataOutputStream dos;
146   ExternallyRolledFileAppender er;
147
148   public
149   HUPNode(Socket socket, ExternallyRolledFileAppender er) {
150     this.socket = socket;
151     this.er = er;
152     try {
153       dis = new DataInputStream(socket.getInputStream());
154       dos = new DataOutputStream(socket.getOutputStream());
155     } catch(InterruptedIOException e) {
156       Thread.currentThread().interrupt();
157       e.printStackTrace();
158     } catch(IOException e) {
159       e.printStackTrace();
160     } catch(RuntimeException e) {
161       e.printStackTrace();
162     }
163   }
164
165   public void run() {
166     try {
167       String line = dis.readUTF();
168       LogLog.debug("Got external roll over signal.");
169       if(ExternallyRolledFileAppender.ROLL_OVER.equals(line)) {
170         synchronized(er) {
171           er.rollOver();
172         }
173         dos.writeUTF(ExternallyRolledFileAppender.OK);
174       }
175       else {
176         dos.writeUTF("Expecting [RollOver] string.");
177       }
178       dos.close();
179     } catch(InterruptedIOException e) {
180       Thread.currentThread().interrupt();
181       LogLog.error("Unexpected exception. Exiting HUPNode.", e);
182     } catch(IOException e) {
183       LogLog.error("Unexpected exception. Exiting HUPNode.", e);
184     } catch(RuntimeException e) {
185       LogLog.error("Unexpected exception. Exiting HUPNode.", e);
186     }
187   }
188 }
189