package abbot.util;
import java.awt.AWTException;
import java.awt.Toolkit;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.PrintStream;
import java.util.Properties;
import javax.swing.UIManager;
import abbot.Log;
/** Preserve and restore system state.
This includes the following:
<ul>
<li><code>System.out/err</code> streams
<li><code>System</code> properties
<li>Security manager
</ul>
*/
public class SystemState {
private static final int CODES[] = {
KeyEvent.VK_CAPS_LOCK,
KeyEvent.VK_NUM_LOCK,
KeyEvent.VK_SCROLL_LOCK,
KeyEvent.VK_KANA_LOCK
};
private Properties oldProps;
private PrintStream oldOut;
private PrintStream oldErr;
private SecurityManager oldsm;
private String oldLookAndFeel;
private boolean lockingKeys[];
private static Robot robot = null;
static {
try {
robot = new Robot();
}
catch(AWTException e) {
}
}
/** Take a snapshot of the current System state for later restoration. */
public SystemState() {
lockingKeys = new boolean[CODES.length];
Toolkit toolkit = Toolkit.getDefaultToolkit();
for (int i=0;i < CODES.length;i++) {
try {
lockingKeys[i] = toolkit.getLockingKeyState(CODES[i]);
try {
toolkit.setLockingKeyState(CODES[i], false);
}
catch(UnsupportedOperationException e) {
// Manually toggle the key
if (lockingKeys[i] && robot != null) {
robot.keyPress(CODES[i]);
robot.keyRelease(CODES[i]);
}
}
}
catch(UnsupportedOperationException e) {
// Nothing much we can do
}
}
oldLookAndFeel = UIManager.getLookAndFeel().getClass().getName();
oldOut = System.out;
oldErr = System.err;
System.setOut(new ProtectedStream(oldOut));
System.setErr(new ProtectedStream(oldErr));
oldProps = (Properties)System.getProperties().clone();
oldsm = System.getSecurityManager();
}
/** Restore the state captured in the ctor. */
public void restore() {
System.setSecurityManager(oldsm);
System.setProperties(oldProps);
System.setOut(oldOut);
System.setErr(oldErr);
try { UIManager.setLookAndFeel(oldLookAndFeel); }
catch(Exception e) { Log.warn("Could not restore LAF: " + e); }
Toolkit toolkit = Toolkit.getDefaultToolkit();
for (int i=0;i < CODES.length;i++) {
try {
boolean state = toolkit.getLockingKeyState(CODES[i]);
if (state != lockingKeys[i]) {
try {
toolkit.setLockingKeyState(CODES[i], lockingKeys[i]);
}
catch(UnsupportedOperationException e) {
if (robot != null) {
robot.keyPress(CODES[i]);
robot.keyRelease(CODES[i]);
}
}
}
}
catch(UnsupportedOperationException e) {
// Oh, well
}
}
}
/** Provide a wrapper that prevents the original stream from being
closed.
*/
private class ProtectedStream extends PrintStream {
private boolean closed = false;
public ProtectedStream(PrintStream original) {
super(original);
}
public void flush() {
if (!closed)
super.flush();
}
public void close() {
closed = true;
}
public void write(int b) {
if (!closed)
super.write(b);
}
public void write(byte[] buf, int off, int len) {
if (!closed)
super.write(buf, off, len);
}
}
}