001: // CheckpointResource.java
002: // $Id: CheckpointResource.java,v 1.7 2000/08/16 21:37:44 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // please first read the full copyright statement in file COPYRIGHT.HTML
005:
006: package org.w3c.jigsaw.resources;
007:
008: import org.w3c.tools.resources.Attribute;
009: import org.w3c.tools.resources.AttributeHolder;
010: import org.w3c.tools.resources.AttributeRegistry;
011: import org.w3c.tools.resources.BooleanAttribute;
012: import org.w3c.tools.resources.FramedResource;
013: import org.w3c.tools.resources.IntegerAttribute;
014: import org.w3c.tools.resources.Resource;
015: import org.w3c.tools.resources.ServerInterface;
016:
017: import org.w3c.jigsaw.http.Logger;
018: import org.w3c.jigsaw.http.httpd;
019:
020: import java.util.Date;
021:
022: /**
023: * A resource that will checkpoint the configuration at regular intervals.
024: * This resource will make sure that current configuration is backed up to
025: * disk at regular (configurable) intervals.
026: * <p>The webmaster can customize what part of the configuration is to be
027: * backed up through boolean attributes.
028: */
029:
030: public class CheckpointResource extends FramedResource implements
031: Runnable {
032:
033: private static final boolean debug = true;
034:
035: /**
036: * Attribute index - Backup interval, in seconds.
037: */
038: protected static int ATTR_INTERVAL = -1;
039: /**
040: * Attribute index - The priority of the flusher thread.
041: */
042: protected static int ATTR_PRIORITY = -1;
043: /**
044: * Attribute index - Should we flush the logs too ?
045: */
046: protected static int ATTR_FLUSHLOG = -1;
047: /**
048: * Attrbute index - Should we save the properties too ?
049: */
050: protected static int ATTR_FLUSHPROPS = -1;
051: /**
052: * Attribute index - Should we save the configuration ?
053: */
054: protected static int ATTR_FLUSHCONFIG = -1;
055: /**
056: * Attribute index - should we display a trace when we perform checkpoint
057: */
058: protected static int ATTR_TRACE_CHECK = -1;
059:
060: static {
061: Class c = null;
062: Attribute a = null;
063:
064: try {
065: c = Class
066: .forName("org.w3c.jigsaw.resources.CheckpointResource");
067: } catch (Exception ex) {
068: ex.printStackTrace();
069: System.exit(1);
070: }
071: // Register the interval attribute:
072: a = new IntegerAttribute("interval", new Integer(60),
073: Attribute.EDITABLE);
074: ATTR_INTERVAL = AttributeRegistry.registerAttribute(c, a);
075: // Register the flusher thread priority
076: a = new IntegerAttribute("thread-priority", new Integer(2),
077: Attribute.EDITABLE);
078: ATTR_PRIORITY = AttributeRegistry.registerAttribute(c, a);
079: // Register the flushlog boolean property:
080: a = new BooleanAttribute("flush-logs", Boolean.FALSE,
081: Attribute.EDITABLE);
082: ATTR_FLUSHLOG = AttributeRegistry.registerAttribute(c, a);
083: // Register the flush properties property:
084: a = new BooleanAttribute("flush-properties", Boolean.FALSE,
085: Attribute.EDITABLE);
086: ATTR_FLUSHPROPS = AttributeRegistry.registerAttribute(c, a);
087: // Register the flush configuration property:
088: a = new BooleanAttribute("flush-configuration", Boolean.TRUE,
089: Attribute.EDITABLE);
090: ATTR_FLUSHCONFIG = AttributeRegistry.registerAttribute(c, a);
091: // Register the trace property
092: a = new BooleanAttribute("trace-checkpoint", Boolean.FALSE,
093: Attribute.EDITABLE);
094: ATTR_TRACE_CHECK = AttributeRegistry.registerAttribute(c, a);
095: }
096: /**
097: * Our thread, if one is currently attached.
098: */
099: protected Thread thread = null;
100: /**
101: * Last date at which we checkpointed the configuration
102: */
103: protected Date checkpoint = null;
104: /**
105: * Is our attached thread still alive ?
106: */
107: protected boolean alive = false;
108:
109: /**
110: * Start the thread for this object, only if needed.
111: */
112:
113: public synchronized void activate() {
114: if (getFlushLog() || getFlushProperties()
115: || getFlushConfiguration()) {
116: if (getInterval() > 0) {
117: alive = true;
118: if (thread == null) {
119: thread = new Thread(this );
120: thread.setName("checkpointer");
121: thread.setPriority(getPriority());
122: thread.start();
123: return;
124: } else {
125: return;
126: }
127: }
128: }
129: // The thread should not be running any more, stop and kill it:
130: if (thread != null) {
131: alive = false;
132: thread.stop();
133: thread = null;
134: }
135: return;
136: }
137:
138: /**
139: * Force our attached thread to stop.
140: */
141:
142: protected synchronized void stop() {
143: alive = false;
144: thread = null;
145: notify();
146: }
147:
148: /**
149: * Get the sync interval.
150: * @return An integer number of seconds, or <strong>-1</strong> if
151: * undefined.
152: */
153:
154: public int getInterval() {
155: return getInt(ATTR_INTERVAL, -1);
156: }
157:
158: /**
159: * Get the priority for our attached thread.
160: * @return An integer priority for the thread, which defaults to
161: * <strong>2</strong> if undefined.
162: */
163:
164: public int getPriority() {
165: return getInt(ATTR_PRIORITY, 2);
166: }
167:
168: /**
169: * Get the flush log flag.
170: * @return A boolean, <strong>true</strong> if the log is to be flushed at
171: * each refresh interval, <strong>false</strong> otherwise.
172: */
173:
174: public boolean getFlushLog() {
175: return getBoolean(ATTR_FLUSHLOG, false);
176: }
177:
178: public boolean getTraceFlag() {
179: return getBoolean(ATTR_TRACE_CHECK, false);
180: }
181:
182: /**
183: * Get the flush properties flag.
184: * @return A boolean, <strong>true</strong> if the properties are to be
185: * flushed, <strong>false</strong> otherwise.
186: */
187:
188: public boolean getFlushProperties() {
189: return getBoolean(ATTR_FLUSHPROPS, false);
190: }
191:
192: /**
193: * Get the flush configuration flag.
194: * @return A boolean, <strong>true</strong> oif the configuration is to be
195: * flushed at each interval, <strong>false</strong> otherwise.
196: */
197:
198: public boolean getFlushConfiguration() {
199: return getBoolean(ATTR_FLUSHCONFIG, true);
200: }
201:
202: /**
203: * This is the only resource that will refuse to be unloaded !
204: * @return Always <strong>false</strong>.
205: */
206:
207: public boolean acceptUnload() {
208: return false;
209: }
210:
211: /**
212: * This resource is being unloaded.
213: * Unloading that object will also stop the thread. However, there is
214: * a bug here, since if the resource gets unloaded for some reason, it
215: * will not be able to wakeup itself at next checkpoint time.
216: */
217:
218: public void notifyUnload() {
219: stop();
220: super .notifyUnload();
221: }
222:
223: /**
224: * We are attached a thread, now it's time to performt the job.
225: */
226:
227: public void run() {
228: httpd server = (httpd) getServer();
229: int interval = -1;
230: try {
231: while (alive) {
232: // Are we still alive ?
233: interval = getInterval();
234: alive = ((getFlushLog() || getFlushProperties() || getFlushConfiguration()) && (interval > 0));
235: if (!alive)
236: break;
237: // Wait for something to do:
238: synchronized (this ) {
239: try {
240: wait(interval * 1000);
241: } catch (InterruptedException ex) {
242: }
243: }
244: // Do what is to be done:
245: checkpoint = new Date();
246: if (getTraceFlag())
247: System.out.println("*** Checkpoint ("
248: + server.getIdentifier() + ") at "
249: + checkpoint);
250: if (alive && getFlushConfiguration())
251: server.checkpoint();
252: if (alive && getFlushLog()) {
253: Logger logger = ((httpd) getServer()).getLogger();
254: if (logger != null)
255: logger.sync();
256: }
257: }
258: } catch (Exception ex) {
259: String msg = ("exception while running \""
260: + ex.getMessage() + "\". Stopped.");
261: server.errlog(this , msg);
262: } finally {
263: thread = null;
264: }
265: }
266:
267: /**
268: * Activate the checkpointer at initialization time.
269: * @poaram values Default attribute values.
270: */
271:
272: public void initialize(Object values[]) {
273: super .initialize(values);
274: try {
275: registerFrameIfNone(
276: "org.w3c.jigsaw.resources.CheckpointFrame",
277: "checkpoint-frame");
278: } catch (Exception ex) {
279: ex.printStackTrace();
280: }
281: }
282: }
|