diff options
| author | tkellner <tkellner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2011-08-01 08:23:21 +0000 | 
|---|---|---|
| committer | tkellner <tkellner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2011-08-01 08:23:21 +0000 | 
| commit | 9d6b88165f30fcbaf1874485112d9ed5d7c78226 (patch) | |
| tree | 3d2e0e11fbf18b3f30aaf006d1eb1df6e69bf26b /BKUWebStart/src | |
| parent | 6fb4b5bf1bd7ea9c693350eacb8b17216e1d8a58 (diff) | |
| download | mocca-9d6b88165f30fcbaf1874485112d9ed5d7c78226.tar.gz mocca-9d6b88165f30fcbaf1874485112d9ed5d7c78226.tar.bz2 mocca-9d6b88165f30fcbaf1874485112d9ed5d7c78226.zip | |
Autostart feature added (Linux, Windows)
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@948 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'BKUWebStart/src')
12 files changed, 1245 insertions, 305 deletions
| diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java index 7bb80860..c3f2a699 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java @@ -68,8 +68,9 @@ public class Configurator {     * allowed: MAJOR[.MINOR[.X[-SNAPSHOT]]]     */    public static final String MIN_CONFIG_VERSION = "1.3.4-SNAPSHOT"; -  public static final String CONFIG_DIR = ".mocca/conf/"; -  public static final String CERTS_DIR = ".mocca/certs/"; +  public static final String BKU_USER_DIR = ".mocca/"; +  public static final String CONFIG_DIR = BKU_USER_DIR + "conf/"; +  public static final String CERTS_DIR = BKU_USER_DIR + "certs/";    public static final String VERSION_FILE = ".version";    public static final String UNKOWN_VERSION = "unknown";    public static final String CONF_TEMPLATE_FILE = "conf-tmp.zip"; diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java index 547b46b6..3fa7f805 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java @@ -22,266 +22,283 @@   */ -package at.gv.egiz.bku.webstart;
 -
 -import at.gv.egiz.bku.webstart.gui.StatusNotifier;
 -import at.gv.egiz.bku.webstart.gui.BKUControllerInterface;
 -import at.gv.egiz.bku.webstart.gui.MOCCAIcon;
 -import iaik.asn1.CodingException;
 -import java.io.IOException;
 -import java.net.URISyntaxException;
 -import java.util.Locale;
 -
 -import javax.jnlp.UnavailableServiceException;
 -
 -//import com.sun.javaws.security.JavaWebStartSecurity;
 -import java.awt.Desktop;
 -import java.awt.SplashScreen;
 -import java.net.BindException;
 -import java.net.MalformedURLException;
 -import java.net.URL;
 -import java.security.GeneralSecurityException;
 -import java.util.jar.Attributes;
 -import java.util.jar.Manifest;
 -import javax.jnlp.BasicService;
 -import javax.jnlp.ServiceManager;
 -import org.mortbay.util.MultiException;
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
 -
 -public class Launcher implements BKUControllerInterface {
 -
 -	public static final String WEBAPP_RESOURCE = "BKULocal.war";
 -	public static final String CERTIFICATES_RESOURCE = "BKUCertificates.jar";
 -	public static final String WEBAPP_FILE = "BKULocal.war";
 -	/** no leading slash for messages, but for image */
 -	public static final String MESSAGES_RESOURCE = "at/gv/egiz/bku/webstart/messages";
 -	public static final String TRAYICON_RESOURCE = "/at/gv/egiz/bku/webstart/chip";
 -	private static Logger log = LoggerFactory.getLogger(Launcher.class);
 -	/** local bku uri */
 -	public static final URL HTTP_SECURITY_LAYER_URL;
 -	public static final URL HTTPS_SECURITY_LAYER_URL;
 -	public static final URL INSTALL_CERT_URL;
 -	public static final URL PIN_MANAGEMENT_URL;
 -	public static final URL HELP_URL;
 -
 -	static {
 -		URL http = null;
 -		URL https = null;
 -		URL pin = null;
 -		URL cert = null;
 -		URL help = null;
 -		try {
 -			http = new URL("http://localhost:" + Integer.getInteger(Container.HTTPS_PORT_PROPERTY, 3495).intValue() + '/');
 -			https = new URL("https://localhost:" + Integer.getInteger(Container.HTTPS_PORT_PROPERTY, 3496).intValue() + '/');
 -			pin = new URL(http, "/PINManagement");
 -			cert = new URL(http, "/ca.crt");
 -			help = new URL(http, "/help/");
 -		} catch (MalformedURLException ex) {
 -			log.error("Failed to create URL.", ex);
 -		} finally {
 -			HTTP_SECURITY_LAYER_URL = http;
 -			HTTPS_SECURITY_LAYER_URL = https;
 -			PIN_MANAGEMENT_URL = pin;
 -			INSTALL_CERT_URL = cert;
 -			HELP_URL = help;
 -		}
 -	}
 -	public static final String version;
 -
 -	static {
 -		String tmp = Configurator.UNKOWN_VERSION;
 -		try {
 -			String bkuWebStartJar = Launcher.class.getProtectionDomain().getCodeSource().getLocation().toString();
 -			URL manifestURL = new URL("jar:" + bkuWebStartJar + "!/META-INF/MANIFEST.MF");
 -			if (log.isTraceEnabled()) {
 -				log.trace("read version information from " + manifestURL);
 -			}
 -			Manifest manifest = new Manifest(manifestURL.openStream());
 -			Attributes atts = manifest.getMainAttributes();
 -			if (atts != null) {
 -				tmp = atts.getValue("Implementation-Build");
 -			}
 -		} catch (IOException ex) {
 -			log.error("failed to read version", ex);
 -		} finally {
 -			version = tmp;
 -			log.info("BKU Web Start " + version);
 -		}
 -	}
 -	private Configurator config;
 -	private Container server;
 -	private BasicService basicService;
 -	private StatusNotifier status;
 -
 -	public Launcher() {
 -		log.info("Initializing Launcher");
 -
 -		// SocketPerm * required (DataURL), FilePermission * write (JFileChooser) required,
 -		// jetty does not allow fine-grained permission config (codeBase?)
 -		// ie. we don't need a security manager
 -		log.trace("disabling (JNLP) security manager");
 -		System.setSecurityManager(null);
 -
 -		status = new MOCCAIcon(this);
 -	}
 -
 -	public void launch() throws Exception {
 -		initStart();
 -		try {
 -			initConfig();
 -		} catch (Exception ex) {
 -			log.error("Failed to initialize configuration", ex);
 -			status.error(StatusNotifier.ERROR_CONFIG);
 -			throw ex;
 -		}
 -		try {
 -			startServer();
 -			initFinished();
 -		} catch (BindException ex) {
 -			log.error("Failed to launch server, " + ex.getMessage(), ex);
 -			status.error(StatusNotifier.ERROR_BIND);
 -			throw ex;
 -		} catch (MultiException ex) {
 -			log.error("Failed to launch server, " + ex.getMessage(), ex);
 -			if (ex.getThrowable(0) instanceof BindException) {
 -				status.error(StatusNotifier.ERROR_BIND);
 -			} else {
 -				status.error(StatusNotifier.ERROR_START);
 -			}
 -			throw ex;
 -		} catch (Exception ex) {
 -			ex.printStackTrace();
 -			log.error("Failed to launch server, " + ex.getMessage(), ex);
 -			status.error(StatusNotifier.ERROR_START);
 -			throw ex;
 -		}
 -	}
 -
 -	private void browse(URL url) throws IOException, URISyntaxException {
 -		// don't use basicService.showDocument(), which causes a java ssl warning dialog
 -		if (Desktop.isDesktopSupported()) {
 -			Desktop desktop = Desktop.getDesktop();
 -			if (desktop.isSupported(Desktop.Action.BROWSE)) {
 -				desktop.browse(url.toURI());
 -				return;
 -			}
 -		}
 -		throw new IOException("current platform does not support Java Desktop API");
 -	}
 -
 -	private void initStart() {
 -		try {
 -			status.info(StatusNotifier.MESSAGE_START);
 -			basicService = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService");
 -			if (basicService.isOffline()) {
 -				log.info("launching MOCCA Web Start offline");
 -			} else {
 -				log.info("launching MOCCA Web Start online");
 -			}
 -		} catch (UnavailableServiceException ex) {
 -			log.info("Failed to obtain JNLP service: " + ex.getMessage());
 -		}
 -	}
 -
 -	private void initConfig() throws IOException, CodingException, GeneralSecurityException {
 -		config = new Configurator();
 -		config.ensureConfiguration();
 -		config.ensureCertificates();
 -	}
 -
 -	private void startServer() throws Exception {
 -		log.info("init servlet container and MOCCA webapp");
 -		server = new Container();
 -		server.init();
 -		server.start();
 -	}
 -
 -	private void initFinished() {
 -		try {
 -			status.info(StatusNotifier.MESSAGE_FINISHED);
 -			// standalone (non-webstart) version has splashscreen
 -			if (SplashScreen.getSplashScreen() != null) {
 -				try {
 -					SplashScreen.getSplashScreen().close();
 -				} catch (IllegalStateException ex) {
 -					log.warn("Failed to close splash screen: " + ex.getMessage());
 -				}
 -			}
 -			if (config.isCertRenewed()) {
 -				try {
 -					if ("".equals(status.getLocale().getLanguage())) {
 -						browse(HTTP_SECURITY_LAYER_URL);
 -					} else {
 -						browse(new URL(HTTP_SECURITY_LAYER_URL, status.getLocale().getLanguage()));
 -					}
 -				} catch (Exception ex) {
 -					log.error("failed to open system browser, install TLS certificate manually: " + HTTPS_SECURITY_LAYER_URL, ex);
 -				}
 -			}
 -			log.info("BKU successfully started");
 -			server.join();
 -		} catch (InterruptedException e) {
 -			log.warn("failed to join server: " + e.getMessage(), e);
 -		}
 -	}
 -
 -	@Override
 -	public void shutDown() {
 -		log.info("Shutting down server");
 -		status.info(StatusNotifier.MESSAGE_SHUTDOWN);
 -		if ((server != null) && (server.isRunning())) {
 -			try {
 -				if (server.isRunning()) {
 -					server.stop();
 -				}
 -			} catch (Exception e) {
 -				log.debug(e.toString());
 -			} finally {
 -				if (server.isRunning()) {
 -					server.destroy();
 -				}
 -			}
 -		}
 -		System.exit(0);
 -	}
 -
 -	public static void main(String[] args) throws InterruptedException, IOException {
 -		try {
 -			Launcher launcher = new Launcher();
 -			launcher.launch();
 -		} catch (Exception ex) {
 -			ex.printStackTrace();
 -			log.debug("Caught exception " + ex.getMessage(), ex);
 -			log.info("waiting to shutdown...");
 -			Thread.sleep(5000);
 -			log.info("exit");
 -			System.exit(-1000);
 -		}
 -	}
 -
 -	@Override
 -	public void showHelp(Locale locale) {
 -		try {
 -			if ("".equals(locale.getLanguage())) {
 -				browse(HELP_URL);
 -			} else {
 -				browse(new URL(HELP_URL, locale.getLanguage()));
 -			}
 -		} catch (Exception ex) {
 -			log.error("Failed to open " + HELP_URL, ex);
 -			status.error(StatusNotifier.ERROR_OPEN_URL, HELP_URL);
 -		}
 -
 -	}
 -
 -	@Override
 -	public void pinManagement(Locale locale) {
 -		new Thread(new PINManagementInvoker(status)).start();
 -	}
 -
 -	@Override
 -	public String getVersion() {
 -		return version;
 -	}
 -}
 +package at.gv.egiz.bku.webstart; + +import at.gv.egiz.bku.webstart.autostart.Autostart; +import at.gv.egiz.bku.webstart.gui.StatusNotifier; +import at.gv.egiz.bku.webstart.gui.BKUControllerInterface; +import at.gv.egiz.bku.webstart.gui.MOCCAIcon; +import iaik.asn1.CodingException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Locale; + +import javax.jnlp.UnavailableServiceException; + +//import com.sun.javaws.security.JavaWebStartSecurity; +import java.awt.Desktop; +import java.awt.SplashScreen; +import java.net.BindException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import javax.jnlp.BasicService; +import javax.jnlp.ServiceManager; +import org.mortbay.util.MultiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Launcher implements BKUControllerInterface { + +	public static final String WEBAPP_RESOURCE = "BKULocal.war"; +	public static final String CERTIFICATES_RESOURCE = "BKUCertificates.jar"; +	public static final String WEBAPP_FILE = "BKULocal.war"; +	/** no leading slash for messages, but for image */ +	public static final String MESSAGES_RESOURCE = "at/gv/egiz/bku/webstart/messages"; +	public static final String TRAYICON_RESOURCE = "/at/gv/egiz/bku/webstart/chip"; +	private static final String WEBSTART_FILENAME = "mocca.jnlp"; +	private static Logger log = LoggerFactory.getLogger(Launcher.class); +	/** local bku uri */ +	public static final URL HTTP_SECURITY_LAYER_URL; +	public static final URL HTTPS_SECURITY_LAYER_URL; +	public static final URL INSTALL_CERT_URL; +	public static final URL PIN_MANAGEMENT_URL; +	public static final URL HELP_URL; + +	static { +		URL http = null; +		URL https = null; +		URL pin = null; +		URL cert = null; +		URL help = null; +		try { +			http = new URL("http://localhost:" + Integer.getInteger(Container.HTTPS_PORT_PROPERTY, 3495).intValue() + '/'); +			https = new URL("https://localhost:" + Integer.getInteger(Container.HTTPS_PORT_PROPERTY, 3496).intValue() + '/'); +			pin = new URL(http, "/PINManagement"); +			cert = new URL(http, "/ca.crt"); +			help = new URL(http, "/help/"); +		} catch (MalformedURLException ex) { +			log.error("Failed to create URL.", ex); +		} finally { +			HTTP_SECURITY_LAYER_URL = http; +			HTTPS_SECURITY_LAYER_URL = https; +			PIN_MANAGEMENT_URL = pin; +			INSTALL_CERT_URL = cert; +			HELP_URL = help; +		} +	} +	public static final String version; + +	static { +		String tmp = Configurator.UNKOWN_VERSION; +		try { +			String bkuWebStartJar = Launcher.class.getProtectionDomain().getCodeSource().getLocation().toString(); +			URL manifestURL = new URL("jar:" + bkuWebStartJar + "!/META-INF/MANIFEST.MF"); +			if (log.isTraceEnabled()) { +				log.trace("read version information from " + manifestURL); +			} +			Manifest manifest = new Manifest(manifestURL.openStream()); +			Attributes atts = manifest.getMainAttributes(); +			if (atts != null) { +				tmp = atts.getValue("Implementation-Build"); +			} +		} catch (IOException ex) { +			log.error("failed to read version", ex); +		} finally { +			version = tmp; +			log.info("BKU Web Start " + version); +		} +	} +	private Configurator config; +	private Container server; +	private BasicService basicService; +	private StatusNotifier status; +	private Autostart autostart; + +	private static URL codeBase; + +	public Launcher() { +		log.info("Initializing Launcher"); + +		// SocketPerm * required (DataURL), FilePermission * write (JFileChooser) required, +		// jetty does not allow fine-grained permission config (codeBase?) +		// ie. we don't need a security manager +		log.trace("disabling (JNLP) security manager"); +		System.setSecurityManager(null); + +		autostart = new Autostart(); +		status = new MOCCAIcon(this); +	} + +	public void launch() throws Exception { +		initStart(); +		try { +			initConfig(); +		} catch (Exception ex) { +			log.error("Failed to initialize configuration", ex); +			status.error(StatusNotifier.ERROR_CONFIG); +			throw ex; +		} +		try { +			startServer(); +			initFinished(); +		} catch (BindException ex) { +			log.error("Failed to launch server, " + ex.getMessage(), ex); +			status.error(StatusNotifier.ERROR_BIND); +			throw ex; +		} catch (MultiException ex) { +			log.error("Failed to launch server, " + ex.getMessage(), ex); +			if (ex.getThrowable(0) instanceof BindException) { +				status.error(StatusNotifier.ERROR_BIND); +			} else { +				status.error(StatusNotifier.ERROR_START); +			} +			throw ex; +		} catch (Exception ex) { +			ex.printStackTrace(); +			log.error("Failed to launch server, " + ex.getMessage(), ex); +			status.error(StatusNotifier.ERROR_START); +			throw ex; +		} +	} + +	private void browse(URL url) throws IOException, URISyntaxException { +		// don't use basicService.showDocument(), which causes a java ssl warning dialog +		if (Desktop.isDesktopSupported()) { +			Desktop desktop = Desktop.getDesktop(); +			if (desktop.isSupported(Desktop.Action.BROWSE)) { +				desktop.browse(url.toURI()); +				return; +			} +		} +		throw new IOException("current platform does not support Java Desktop API"); +	} + +	private void initStart() { +		try { +			status.info(StatusNotifier.MESSAGE_START); +			basicService = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService"); +			codeBase = basicService.getCodeBase(); +			autostart.setWebstartName(codeBase + WEBSTART_FILENAME); +			if (basicService.isOffline()) { +				log.info("launching MOCCA Web Start offline"); +			} else { +				log.info("launching MOCCA Web Start online"); +			} +		} catch (UnavailableServiceException ex) { +			log.info("Failed to obtain JNLP service: " + ex.getMessage()); +		} +	} + +	private void initConfig() throws IOException, CodingException, GeneralSecurityException { +		config = new Configurator(); +		config.ensureConfiguration(); +		config.ensureCertificates(); +	} + +	private void startServer() throws Exception { +		log.info("init servlet container and MOCCA webapp"); +		server = new Container(); +		server.init(); +		server.start(); +	} + +	private void initFinished() { +		try { +			status.info(StatusNotifier.MESSAGE_FINISHED); +			// standalone (non-webstart) version has splashscreen +			if (SplashScreen.getSplashScreen() != null) { +				try { +					SplashScreen.getSplashScreen().close(); +				} catch (IllegalStateException ex) { +					log.warn("Failed to close splash screen: " + ex.getMessage()); +				} +			} +			if (config.isCertRenewed()) { +				try { +					if ("".equals(status.getLocale().getLanguage())) { +						browse(HTTP_SECURITY_LAYER_URL); +					} else { +						browse(new URL(HTTP_SECURITY_LAYER_URL, status.getLocale().getLanguage())); +					} +				} catch (Exception ex) { +					log.error("failed to open system browser, install TLS certificate manually: " + HTTPS_SECURITY_LAYER_URL, ex); +				} +			} +			log.info("BKU successfully started"); +			server.join(); +		} catch (InterruptedException e) { +			log.warn("failed to join server: " + e.getMessage(), e); +		} +	} + +	@Override +	public void shutDown() { +		log.info("Shutting down server"); +		status.info(StatusNotifier.MESSAGE_SHUTDOWN); +		if ((server != null) && (server.isRunning())) { +			try { +				if (server.isRunning()) { +					server.stop(); +				} +			} catch (Exception e) { +				log.debug(e.toString()); +			} finally { +				if (server.isRunning()) { +					server.destroy(); +				} +			} +		} +		System.exit(0); +	} + +	public static void main(String[] args) throws InterruptedException, IOException { +		try { +			Launcher launcher = new Launcher(); +			launcher.launch(); +		} catch (Exception ex) { +			ex.printStackTrace(); +			log.debug("Caught exception " + ex.getMessage(), ex); +			log.info("waiting to shutdown..."); +			Thread.sleep(5000); +			log.info("exit"); +			System.exit(-1000); +		} +	} + +	@Override +	public void showHelp(Locale locale) { +		try { +			if ("".equals(locale.getLanguage())) { +				browse(HELP_URL); +			} else { +				browse(new URL(HELP_URL, locale.getLanguage())); +			} +		} catch (Exception ex) { +			log.error("Failed to open " + HELP_URL, ex); +			status.error(StatusNotifier.ERROR_OPEN_URL, HELP_URL); +		} + +	} + +	@Override +	public void pinManagement(Locale locale) { +		new Thread(new PINManagementInvoker(status)).start(); +	} + +	@Override +	public String getVersion() { +		return version; +	} + +	@Override +	public boolean isAutostartEnabled() { +		return autostart.isEnabled(); +	} +	@Override +	public boolean setAutostart(boolean doAutostart) { +		return autostart.set(doAutostart); +	} +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AbstractAutostart.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AbstractAutostart.java new file mode 100644 index 00000000..5e7966b8 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AbstractAutostart.java @@ -0,0 +1,38 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.gv.egiz.bku.webstart.autostart; + +public abstract class AbstractAutostart implements AutostartInterface { +	protected static final String AUTOSTART_FILENAME_PREFIX = "MOCCA"; + +	String _os = System.getProperty("os.name"); +	String _userHome = System.getProperty("user.home") + System.getProperty("file.separator"); +	String _webstartName = null; + +	@Override +	public void setWebstartName(String webstartName) { +		_webstartName = webstartName; +	} +	 +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/Autostart.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/Autostart.java new file mode 100644 index 00000000..a3291d05 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/Autostart.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.gv.egiz.bku.webstart.autostart; + +public class Autostart { +	private static AutostartInterface _autostart = null; + +	private String _webstartName = null; + +	private AutostartInterface getAutostart() +	{ +		if (_autostart == null) +		{ +			String os = System.getProperty("os.name"); +			if (os.equalsIgnoreCase("linux")) +				_autostart = new AutostartLinux(); +			else if (os.toLowerCase().contains("windows")) +				_autostart = new AutostartWindows(); +			if (_webstartName != null) +				_autostart.setWebstartName(_webstartName); +		} + +		return _autostart; +	} + +	public boolean isEnabled() { +		if (getAutostart() == null) +			return false; +		 +		return getAutostart().isEnabled(); +	} + +	public boolean set(boolean enable) { +		if (getAutostart() == null) +			return false; +		 +		return getAutostart().set(enable); +	} + +	public void setWebstartName(String webstartName) { +		if (_autostart == null) +			_webstartName = webstartName; +		else +			_autostart.setWebstartName(webstartName); +	} + +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartInterface.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartInterface.java new file mode 100644 index 00000000..f085fc94 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartInterface.java @@ -0,0 +1,30 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.gv.egiz.bku.webstart.autostart; + +public interface AutostartInterface { +	public boolean isEnabled(); +	public boolean set(boolean enable); +	public void setWebstartName(String webstartName); +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartLinux.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartLinux.java new file mode 100644 index 00000000..4fc91a30 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartLinux.java @@ -0,0 +1,135 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.gv.egiz.bku.webstart.autostart; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AutostartLinux extends AbstractAutostart { +	private static Logger log = LoggerFactory.getLogger(AutostartLinux.class); + +	private Map<String, String> getAutostartFiles() +	{ +		Map<String, String> autostartFiles = new HashMap<String, String>(); +		String autostartFileName, autostartFileContent; +		String autostartCommand = "javaws -Xnosplash " + _webstartName; +		 +		// KDE Autostart +		File f = new File(_userHome + ".kde/Autostart"); +		if ((f.exists()) && (f.isDirectory())) { +			autostartFileName = _userHome + ".kde/Autostart/" +				+ AUTOSTART_FILENAME_PREFIX + ".sh"; +			autostartFileContent = "#!/bin/sh\n" + autostartCommand + "\n"; +			autostartFiles.put(autostartFileName, autostartFileContent); +		} + +		// Gnome Autostart +		f = new File(_userHome + ".config/autostart"); +		if ((f.exists()) && (f.isDirectory())) { +			autostartFileName = _userHome + ".config/autostart/" +					+ AUTOSTART_FILENAME_PREFIX + ".desktop"; +			autostartFileContent = +				"[Desktop Entry]\n" + +				"Name=" + AUTOSTART_FILENAME_PREFIX + "\n" + +				"Type=Application\n" + +				"Exec=" + autostartCommand + "\n" + +				"Terminal=false\n" + +				"Hidden=false\n"; +			autostartFiles.put(autostartFileName, autostartFileContent); +		} +		return autostartFiles; +	} + +	@Override +	public boolean isEnabled() { +		Map<String, String> autostartFiles = getAutostartFiles(); + +		if (autostartFiles.isEmpty()) +			return false; + +		for (Map.Entry<String, String> file : autostartFiles.entrySet()) { +			String autostartFileName = file.getKey(); +			try { +				File f = new File(autostartFileName); +				if (f.exists()) +					return true; +			} catch (Exception e) { +				// ignore +			} +		} +		return false; +	} + +	@Override +	public boolean set(boolean enable) { +		Map<String, String> autostartFiles = getAutostartFiles(); + +		if (autostartFiles.isEmpty()) +			return false; + +		boolean ret = false; +		for (Map.Entry<String, String> file : autostartFiles.entrySet()) { +			String autostartFileName = file.getKey(); +			String autostartFileContent = file.getValue(); +			File f = new File(autostartFileName); + +			if (enable) +			{ +				log.debug("Enabling AutoStart (" + autostartFileName + ")"); +				try { +					FileWriter fw = new FileWriter(f, false); +					BufferedWriter bw = new BufferedWriter(fw); +					bw.write(autostartFileContent); +					bw.flush(); +					bw.close(); +					fw.close(); +					if (autostartFileName.contains(".kde")) +						f.setExecutable(true, false); +					f.setReadable(true, false); +					ret = true; +				} catch (Exception e) { +					log.error("Failed to add autostart file", e); +				} +			} +			else +			{ +				log.debug("Disabling AutoStart (" + autostartFileName + ")"); +				try { +					f.delete(); +				} catch (Exception e) { +					log.error("Failed to remove autostart file", e); +				} +			} +		} + +		return ret; +	} + +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartWindows.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartWindows.java new file mode 100644 index 00000000..50c38d97 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/AutostartWindows.java @@ -0,0 +1,207 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.gv.egiz.bku.webstart.autostart; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.channels.FileChannel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AutostartWindows extends AbstractAutostart { +	private static Logger log = LoggerFactory.getLogger(AutostartWindows.class); +	private static final String DESKTOP_SHORTCUT_NAME = "MOCCA Start.lnk"; + +	private String _linkname = null; + +	public AutostartWindows() { +		try { +			// BKA Workaround: If shortcut exists on desktop, use it for autostart +			_linkname = WinRegistry.readString( +							WinRegistry.HKEY_CURRENT_USER, +							"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", +							"Desktop") +					+ "\\" + DESKTOP_SHORTCUT_NAME; +			File f = new File(_linkname); +			if (f.exists()) +				return; +			_linkname = WinRegistry.readString( +							WinRegistry.HKEY_LOCAL_MACHINE, +							"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", +							"Common Desktop") +					+ "\\" + DESKTOP_SHORTCUT_NAME; +			f = new File(_linkname); +			if (f.exists()) +				return; +			_linkname = null; +		} catch (Exception e) { +			log.debug("Registry reading failed", e); +		} +	} + +	private static boolean copyFile(File srcF, File dstF) { +		boolean ret = false; +		try { +			if (!dstF.exists()) +				dstF.createNewFile(); +			FileChannel src = null; +			FileChannel dst = null; +			try { +				src = new FileInputStream(srcF).getChannel(); +				dst = new FileOutputStream(dstF).getChannel(); +				if (dst.transferFrom(src, 0, src.size()) < src.size()) { +					dst.close(); +					dst = null; +					dstF.delete(); +					log.error("Failed to copy autostart shortcut"); +				} else +					ret = true; +			} catch (FileNotFoundException e) { +				log.error("Failed to copy autostart shortcut", e); +			} finally { +				if (src != null) +					src.close(); +				if (dst != null) +					dst.close(); +			} +		} catch (IOException e) { +			log.error("Failed to copy autostart shortcut", e); +		} +		return ret; +	} + +	private static boolean createFile(File f, String content) { +		try { +			FileWriter fw = new FileWriter(f, false); +			BufferedWriter bw = new BufferedWriter(fw); +			bw.write(content); +			bw.flush(); +			bw.close(); +			fw.close(); +			f.setExecutable(true); +			return true; +		} catch (Exception e) { +			log.error("Failed to add autostart file", e); +		} +		return false; +	} + +	private String getAutostartFileName() { +		String fileName = AUTOSTART_FILENAME_PREFIX +				+ (_linkname != null ? ".lnk" : ".bat"); +		String autostartFileName = null; +		try { +			autostartFileName = WinRegistry +					.readString( +							WinRegistry.HKEY_CURRENT_USER, +							"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", +							"Startup"); +			if (autostartFileName == null) +				throw new Exception("Null returned"); +			autostartFileName += "\\" + fileName; +		} catch (Exception e) { +			log.debug("Registry reading failed - trying fallback", e); + +			String autostartFolderPaths[] = { +					_userHome + "Startmenü\\Programme\\Autostart", // German +																	// Windows +																	// default +																	// autostart +																	// path +					_userHome + "Startmenu\\Programs\\Startup" // English +																// Windows +																// default +																// autostart +																// path +			}; + +			for (String path : autostartFolderPaths) { +				File f = new File(path); +				if (f.exists()) { +					autostartFileName = _userHome + path + "\\" + fileName; +					break; +				} +			} +		} +		return autostartFileName; +	} + +	@Override +	public boolean isEnabled() { +		String autostartFileName = getAutostartFileName(); + +		if (autostartFileName == null) +			return false; + +		try { +			File f = new File(autostartFileName); +			if (f.exists()) +				return true; +		} catch (Exception e) { +			// ignore +		} +		return false; +	} + +	@Override +	public boolean set(boolean enable) { +		String autostartFileName = getAutostartFileName(); + +		if (autostartFileName == null) +			return false; + +		String javaws_loc = System.getProperty("java.home") +				+ "\\bin\\javaws.exe"; +		File f = new File(javaws_loc); +		if (!f.exists()) +			javaws_loc = "javaws.exe"; +		String autostartFileContent = "@\"" + javaws_loc + "\" -Xnosplash " +				+ _webstartName + "\r\n"; + +		f = new File(autostartFileName); + +		if (enable) { +			log.debug("Enabling AutoStart (" + autostartFileName + ")"); +			if (_linkname != null) +				return copyFile(new File(_linkname), f); +			else +				return createFile(f, autostartFileContent); +		} else { +			log.debug("Disabling AutoStart (" + autostartFileName + ")"); +			try { +				f.delete(); +			} catch (Exception e) { +				log.error("Failed to remove autostart file", e); +			} +			return false; +		} +	} + +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/WinRegistry.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/WinRegistry.java new file mode 100644 index 00000000..8a79d227 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/autostart/WinRegistry.java @@ -0,0 +1,386 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.gv.egiz.bku.webstart.autostart; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.ArrayList; +import java.util.List; +import java.util.prefs.Preferences; + +public class WinRegistry { +	public static final int HKEY_CURRENT_USER = 0x80000001; +	public static final int HKEY_LOCAL_MACHINE = 0x80000002; +	public static final int REG_SUCCESS = 0; +	public static final int REG_NOTFOUND = 2; +	public static final int REG_ACCESSDENIED = 5; + +//	private static final int KEY_ALL_ACCESS = 0xf003f; +	private static final int KEY_READ = 0x20019; +	private static Preferences userRoot = Preferences.userRoot(); +	private static Preferences systemRoot = Preferences.systemRoot(); +	private static Class<? extends Preferences> userClass = userRoot.getClass(); +	private static Method regOpenKey = null; +	private static Method regCloseKey = null; +	private static Method regQueryValueEx = null; +	private static Method regEnumValue = null; +	private static Method regQueryInfoKey = null; +	private static Method regEnumKeyEx = null; +//	private static Method regCreateKeyEx = null; +//	private static Method regSetValueEx = null; +//	private static Method regDeleteKey = null; +//	private static Method regDeleteValue = null; + +	static { +		try { +			regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey", +					new Class[] { int.class, byte[].class, int.class }); +			regOpenKey.setAccessible(true); +			regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey", +					new Class[] { int.class }); +			regCloseKey.setAccessible(true); +			regQueryValueEx = userClass.getDeclaredMethod( +					"WindowsRegQueryValueEx", new Class[] { int.class, +							byte[].class }); +			regQueryValueEx.setAccessible(true); +			regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue", +					new Class[] { int.class, int.class, int.class }); +			regEnumValue.setAccessible(true); +			regQueryInfoKey = userClass.getDeclaredMethod( +					"WindowsRegQueryInfoKey1", new Class[] { int.class }); +			regQueryInfoKey.setAccessible(true); +			regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx", +					new Class[] { int.class, int.class, int.class }); +			regEnumKeyEx.setAccessible(true); +//			regCreateKeyEx = userClass.getDeclaredMethod( +//					"WindowsRegCreateKeyEx", new Class[] { int.class, +//							byte[].class }); +//			regCreateKeyEx.setAccessible(true); +//			regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx", +//					new Class[] { int.class, byte[].class, byte[].class }); +//			regSetValueEx.setAccessible(true); +//			regDeleteValue = userClass.getDeclaredMethod( +//					"WindowsRegDeleteValue", new Class[] { int.class, +//							byte[].class }); +//			regDeleteValue.setAccessible(true); +//			regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", +//					new Class[] { int.class, byte[].class }); +//			regDeleteKey.setAccessible(true); +		} catch (Exception e) { +			e.printStackTrace(); +		} +	} + +	private WinRegistry() { +	} + +	/** +	 * Read a value from key and value name +	 *  +	 * @param hkey +	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE +	 * @param key +	 * @param valueName +	 * @return the value +	 * @throws IllegalArgumentException +	 * @throws IllegalAccessException +	 * @throws InvocationTargetException +	 */ +	public static String readString(int hkey, String key, String valueName) +			throws IllegalArgumentException, IllegalAccessException, +			InvocationTargetException { +		if (hkey == HKEY_LOCAL_MACHINE) { +			return readString(systemRoot, hkey, key, valueName); +		} else if (hkey == HKEY_CURRENT_USER) { +			return readString(userRoot, hkey, key, valueName); +		} else { +			throw new IllegalArgumentException("hkey=" + hkey); +		} +	} + +	/** +	 * Read value(s) and value name(s) form given key +	 *  +	 * @param hkey +	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE +	 * @param key +	 * @return the value name(s) plus the value(s) +	 * @throws IllegalArgumentException +	 * @throws IllegalAccessException +	 * @throws InvocationTargetException +	 */ +	public static Map<String, String> readStringValues(int hkey, String key) +			throws IllegalArgumentException, IllegalAccessException, +			InvocationTargetException { +		if (hkey == HKEY_LOCAL_MACHINE) { +			return readStringValues(systemRoot, hkey, key); +		} else if (hkey == HKEY_CURRENT_USER) { +			return readStringValues(userRoot, hkey, key); +		} else { +			throw new IllegalArgumentException("hkey=" + hkey); +		} +	} + +	/** +	 * Read the value name(s) from a given key +	 *  +	 * @param hkey +	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE +	 * @param key +	 * @return the value name(s) +	 * @throws IllegalArgumentException +	 * @throws IllegalAccessException +	 * @throws InvocationTargetException +	 */ +	public static List<String> readStringSubKeys(int hkey, String key) +			throws IllegalArgumentException, IllegalAccessException, +			InvocationTargetException { +		if (hkey == HKEY_LOCAL_MACHINE) { +			return readStringSubKeys(systemRoot, hkey, key); +		} else if (hkey == HKEY_CURRENT_USER) { +			return readStringSubKeys(userRoot, hkey, key); +		} else { +			throw new IllegalArgumentException("hkey=" + hkey); +		} +	} + +//	/** +//	 * Create a key +//	 *  +//	 * @param hkey +//	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE +//	 * @param key +//	 * @throws IllegalArgumentException +//	 * @throws IllegalAccessException +//	 * @throws InvocationTargetException +//	 */ +//	public static void createKey(int hkey, String key) +//			throws IllegalArgumentException, IllegalAccessException, +//			InvocationTargetException { +//		int[] ret; +//		if (hkey == HKEY_LOCAL_MACHINE) { +//			ret = createKey(systemRoot, hkey, key); +//			regCloseKey +//					.invoke(systemRoot, new Object[] { new Integer(ret[0]) }); +//		} else if (hkey == HKEY_CURRENT_USER) { +//			ret = createKey(userRoot, hkey, key); +//			regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) }); +//		} else { +//			throw new IllegalArgumentException("hkey=" + hkey); +//		} +//		if (ret[1] != REG_SUCCESS) { +//			throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key); +//		} +//	} + +//	/** +//	 * Write a value in a given key/value name +//	 *  +//	 * @param hkey +//	 * @param key +//	 * @param valueName +//	 * @param value +//	 * @throws IllegalArgumentException +//	 * @throws IllegalAccessException +//	 * @throws InvocationTargetException +//	 */ +//	public static void writeStringValue(int hkey, String key, String valueName, +//			String value) throws IllegalArgumentException, +//			IllegalAccessException, InvocationTargetException { +//		if (hkey == HKEY_LOCAL_MACHINE) { +//			writeStringValue(systemRoot, hkey, key, valueName, value); +//		} else if (hkey == HKEY_CURRENT_USER) { +//			writeStringValue(userRoot, hkey, key, valueName, value); +//		} else { +//			throw new IllegalArgumentException("hkey=" + hkey); +//		} +//	} + +//	/** +//	 * Delete a given key +//	 *  +//	 * @param hkey +//	 * @param key +//	 * @throws IllegalArgumentException +//	 * @throws IllegalAccessException +//	 * @throws InvocationTargetException +//	 */ +//	public static void deleteKey(int hkey, String key) +//			throws IllegalArgumentException, IllegalAccessException, +//			InvocationTargetException { +//		int rc = -1; +//		if (hkey == HKEY_LOCAL_MACHINE) { +//			rc = deleteKey(systemRoot, hkey, key); +//		} else if (hkey == HKEY_CURRENT_USER) { +//			rc = deleteKey(userRoot, hkey, key); +//		} +//		if (rc != REG_SUCCESS) { +//			throw new IllegalArgumentException("rc=" + rc + "  key=" + key); +//		} +//	} + +//	/** +//	 * delete a value from a given key/value name +//	 *  +//	 * @param hkey +//	 * @param key +//	 * @param value +//	 * @throws IllegalArgumentException +//	 * @throws IllegalAccessException +//	 * @throws InvocationTargetException +//	 */ +//	public static void deleteValue(int hkey, String key, String value) +//			throws IllegalArgumentException, IllegalAccessException, +//			InvocationTargetException { +//		int rc = -1; +//		if (hkey == HKEY_LOCAL_MACHINE) { +//			rc = deleteValue(systemRoot, hkey, key, value); +//		} else if (hkey == HKEY_CURRENT_USER) { +//			rc = deleteValue(userRoot, hkey, key, value); +//		} +//		if (rc != REG_SUCCESS) { +//			throw new IllegalArgumentException("rc=" + rc + "  key=" + key +//					+ "  value=" + value); +//		} +//	} + +	// ===================== + +//	private static int deleteValue(Preferences root, int hkey, String key, +//			String value) throws IllegalArgumentException, +//			IllegalAccessException, InvocationTargetException { +//		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] { +//				new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) }); +//		if (handles[1] != REG_SUCCESS) { +//			return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED +//		} +//		int rc = ((Integer) regDeleteValue.invoke(root, new Object[] { +//				new Integer(handles[0]), toCstr(value) })).intValue(); +//		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) }); +//		return rc; +//	} + +//	private static int deleteKey(Preferences root, int hkey, String key) +//			throws IllegalArgumentException, IllegalAccessException, +//			InvocationTargetException { +//		int rc = ((Integer) regDeleteKey.invoke(root, new Object[] { +//				new Integer(hkey), toCstr(key) })).intValue(); +//		return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS +//	} + +	private static String readString(Preferences root, int hkey, String key, +			String value) throws IllegalArgumentException, +			IllegalAccessException, InvocationTargetException { +		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] { +				new Integer(hkey), toCstr(key), new Integer(KEY_READ) }); +		if (handles[1] != REG_SUCCESS) { +			return null; +		} +		byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] { +				new Integer(handles[0]), toCstr(value) }); +		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) }); +		return (valb != null ? new String(valb).trim() : null); +	} + +	private static Map<String, String> readStringValues(Preferences root, +			int hkey, String key) throws IllegalArgumentException, +			IllegalAccessException, InvocationTargetException { +		HashMap<String, String> results = new HashMap<String, String>(); +		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] { +				new Integer(hkey), toCstr(key), new Integer(KEY_READ) }); +		if (handles[1] != REG_SUCCESS) { +			return null; +		} +		int[] info = (int[]) regQueryInfoKey.invoke(root, +				new Object[] { new Integer(handles[0]) }); + +		int count = info[2]; // count +		int maxlen = info[3]; // value length max +		for (int index = 0; index < count; index++) { +			byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] { +					new Integer(handles[0]), new Integer(index), +					new Integer(maxlen + 1) }); +			String value = readString(hkey, key, new String(name)); +			results.put(new String(name).trim(), value); +		} +		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) }); +		return results; +	} + +	private static List<String> readStringSubKeys(Preferences root, int hkey, +			String key) throws IllegalArgumentException, +			IllegalAccessException, InvocationTargetException { +		List<String> results = new ArrayList<String>(); +		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] { +				new Integer(hkey), toCstr(key), new Integer(KEY_READ) }); +		if (handles[1] != REG_SUCCESS) { +			return null; +		} +		int[] info = (int[]) regQueryInfoKey.invoke(root, +				new Object[] { new Integer(handles[0]) }); + +		int count = info[2]; // count +		int maxlen = info[3]; // value length max +		for (int index = 0; index < count; index++) { +			byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] { +					new Integer(handles[0]), new Integer(index), +					new Integer(maxlen + 1) }); +			results.add(new String(name).trim()); +		} +		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) }); +		return results; +	} + +//	private static int[] createKey(Preferences root, int hkey, String key) +//			throws IllegalArgumentException, IllegalAccessException, +//			InvocationTargetException { +//		return (int[]) regCreateKeyEx.invoke(root, new Object[] { +//				new Integer(hkey), toCstr(key) }); +//	} + +//	private static void writeStringValue(Preferences root, int hkey, +//			String key, String valueName, String value) +//			throws IllegalArgumentException, IllegalAccessException, +//			InvocationTargetException { +//		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] { +//				new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) }); +// +//		regSetValueEx.invoke(root, new Object[] { new Integer(handles[0]), +//				toCstr(valueName), toCstr(value) }); +//		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) }); +//	} + +	// utility +	private static byte[] toCstr(String str) { +		byte[] result = new byte[str.length() + 1]; + +		for (int i = 0; i < str.length(); i++) { +			result[i] = (byte) str.charAt(i); +		} +		result[str.length()] = 0; +		return result; +	} +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/BKUControllerInterface.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/BKUControllerInterface.java index 16067614..91ce0e77 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/BKUControllerInterface.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/BKUControllerInterface.java @@ -36,4 +36,17 @@ public interface BKUControllerInterface {  	public void pinManagement(Locale locale); + +	/** +	 * Check if MOCCA Autostart is enabled +	 * @return autostart state +	 */ +	boolean isAutostartEnabled(); + +	/** +	 * Set MOCCA Autostart +	 * @param doAutostart whether to enable or disable autostart +	 * @return new autostart state +	 */ +	public boolean setAutostart(boolean doAutostart);  } diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/MOCCAIcon.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/MOCCAIcon.java index afc14889..d6dc6d5b 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/MOCCAIcon.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/MOCCAIcon.java @@ -21,17 +21,20 @@   * that you distribute must include a readable copy of the "NOTICE" text file.   */ -  package at.gv.egiz.bku.webstart.gui;  import java.awt.AWTException; +import java.awt.CheckboxMenuItem;  import java.awt.Image; +import java.awt.Menu;  import java.awt.MenuItem;  import java.awt.PopupMenu;  import java.awt.SystemTray;  import java.awt.TrayIcon;  import java.awt.event.ActionEvent;  import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener;  import java.awt.event.WindowAdapter;  import java.io.IOException;  import java.text.MessageFormat; @@ -43,21 +46,24 @@ import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  /** - * - * @author clemens + * @author clemenso + * @author tkellner   */ -public class MOCCAIcon implements StatusNotifier, ActionListener { +public class MOCCAIcon implements StatusNotifier, ActionListener, ItemListener {  	public static final String LABEL_SHUTDOWN = "tray.label.shutdown";  	public static final String LABEL_PIN = "tray.label.pin";  	public static final String LABEL_HELP = "tray.label.help";  	public static final String LABEL_ABOUT = "tray.label.about"; +	public static final String LABEL_SETTINGS = "tray.label.settings"; +	public static final String LABEL_AUTOSTART = "tray.label.autostart";  	public static final String TOOLTIP_DEFAULT = "tray.tooltip.default"; +  	/** action commands for tray menu */ -	public static final String SHUTDOWN_COMMAND = "shutdown"; -	public static final String PIN_COMMAND = "pin"; -	public static final String ABOUT_COMMAND = "about"; -	public static final String HELP_COMMAND = "help"; +	private static enum COMMANDS { +		SHUTDOWN_COMMAND, PIN_COMMAND, ABOUT_COMMAND, HELP_COMMAND, AUTOSTART_COMMAND +	}; +  	private static final Logger log = LoggerFactory.getLogger(MOCCAIcon.class);  	protected BKUControllerInterface controller;  	protected TrayIcon trayIcon; @@ -67,7 +73,8 @@ public class MOCCAIcon implements StatusNotifier, ActionListener {  	public MOCCAIcon(BKUControllerInterface controller) {  		this.controller = controller; -		messages = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault()); +		messages = ResourceBundle.getBundle(MESSAGES_RESOURCE, +				Locale.getDefault());  		this.trayIcon = initTrayIcon();  	} @@ -88,33 +95,49 @@ public class MOCCAIcon implements StatusNotifier, ActionListener {  				} else {  					iconResource = TRAYICON_RESOURCE + "48.png";  				} -				Image image = ImageIO.read(getClass().getResourceAsStream(iconResource)); +				Image image = ImageIO.read(getClass().getResourceAsStream( +						iconResource));  				PopupMenu menu = new PopupMenu();  				MenuItem helpItem = new MenuItem(messages.getString(LABEL_HELP));  				helpItem.addActionListener(this); -				helpItem.setActionCommand(HELP_COMMAND); +				helpItem.setActionCommand(COMMANDS.HELP_COMMAND.name());  				menu.add(helpItem);  				MenuItem pinItem = new MenuItem(messages.getString(LABEL_PIN));  				pinItem.addActionListener(this); -				pinItem.setActionCommand(PIN_COMMAND); +				pinItem.setActionCommand(COMMANDS.PIN_COMMAND.name());  				menu.add(pinItem); -				MenuItem shutdownItem = new MenuItem(messages.getString(LABEL_SHUTDOWN)); -				shutdownItem.addActionListener(this); -				shutdownItem.setActionCommand(SHUTDOWN_COMMAND); -				menu.add(shutdownItem); +				MenuItem aboutItem = new MenuItem( +						messages.getString(LABEL_ABOUT)); +				aboutItem.setActionCommand(COMMANDS.ABOUT_COMMAND.name()); +				aboutItem.addActionListener(this); +				menu.add(aboutItem);  				menu.addSeparator(); -				MenuItem aboutItem = new MenuItem(messages.getString(LABEL_ABOUT)); -				aboutItem.setActionCommand(ABOUT_COMMAND); -				aboutItem.addActionListener(this); -				menu.add(aboutItem); +				Menu settingsMenu = new Menu(messages.getString(LABEL_SETTINGS)); +				menu.add(settingsMenu); + +				CheckboxMenuItem autostartItem = new CheckboxMenuItem( +						messages.getString(LABEL_AUTOSTART)); +				autostartItem.addItemListener(this); +				autostartItem.setActionCommand(COMMANDS.AUTOSTART_COMMAND.name()); +				autostartItem.setState(controller.isAutostartEnabled()); +				settingsMenu.add(autostartItem); -				TrayIcon ti = new TrayIcon(image, messages.getString(TOOLTIP_DEFAULT), menu); +				menu.addSeparator(); + +				MenuItem shutdownItem = new MenuItem( +						messages.getString(LABEL_SHUTDOWN)); +				shutdownItem.addActionListener(this); +				shutdownItem.setActionCommand(COMMANDS.SHUTDOWN_COMMAND.name()); +				menu.add(shutdownItem); + +				TrayIcon ti = new TrayIcon(image, +						messages.getString(TOOLTIP_DEFAULT), menu);  				ti.setImageAutoSize(true);  				ti.addActionListener(this);  				tray.add(ti); @@ -133,10 +156,8 @@ public class MOCCAIcon implements StatusNotifier, ActionListener {  	@Override  	public void error(String msgKey) {  		if (trayIcon != null) { -			trayIcon.displayMessage( -							messages.getString(CAPTION_ERROR), -							messages.getString(msgKey), -							TrayIcon.MessageType.ERROR); +			trayIcon.displayMessage(messages.getString(CAPTION_ERROR), +					messages.getString(msgKey), TrayIcon.MessageType.ERROR);  		} else {  			log.error(messages.getString(msgKey));  		} @@ -145,22 +166,20 @@ public class MOCCAIcon implements StatusNotifier, ActionListener {  	@Override  	public void error(String msgPatternKey, Object... argument) {  		if (trayIcon != null) { -			trayIcon.displayMessage( -							messages.getString(CAPTION_ERROR), -							MessageFormat.format(messages.getString(msgPatternKey), argument), -							TrayIcon.MessageType.ERROR); +			trayIcon.displayMessage(messages.getString(CAPTION_ERROR), +					MessageFormat.format(messages.getString(msgPatternKey), +							argument), TrayIcon.MessageType.ERROR);  		} else { -			log.error(MessageFormat.format(messages.getString(msgPatternKey), argument)); +			log.error(MessageFormat.format(messages.getString(msgPatternKey), +					argument));  		}  	}  	@Override  	public void info(String msgKey) {  		if (trayIcon != null) { -			trayIcon.displayMessage( -							messages.getString(CAPTION_DEFAULT), -							messages.getString(msgKey), -							TrayIcon.MessageType.INFO); +			trayIcon.displayMessage(messages.getString(CAPTION_DEFAULT), +					messages.getString(msgKey), TrayIcon.MessageType.INFO);  		} else {  			log.info(messages.getString(msgKey));  		} @@ -173,18 +192,23 @@ public class MOCCAIcon implements StatusNotifier, ActionListener {  	/**  	 * Listen for TrayMenu actions (display error messages on trayIcon) +	 *   	 * @param e  	 */  	@Override  	public void actionPerformed(ActionEvent e) { -		if (SHUTDOWN_COMMAND.equals(e.getActionCommand())) { +		switch (COMMANDS.valueOf(e.getActionCommand())) { +		case SHUTDOWN_COMMAND:  			log.debug("shutdown requested via tray menu");  			controller.shutDown(); -		} else if (ABOUT_COMMAND.equals(e.getActionCommand())) { +			break; + +		case ABOUT_COMMAND:  			log.debug("about dialog requested via tray menu");  			if (aboutDialog == null) { -				aboutDialog = new AboutDialog(new JFrame(), true, controller.getVersion()); +				aboutDialog = new AboutDialog(new JFrame(), true, +						controller.getVersion());  				aboutDialog.addWindowListener(new WindowAdapter() {  					@Override @@ -195,17 +219,34 @@ public class MOCCAIcon implements StatusNotifier, ActionListener {  			}  			aboutDialog.setLocationByPlatform(true);  			aboutDialog.setVisible(true); +			break; -		} else if (PIN_COMMAND.equals(e.getActionCommand())) { +		case PIN_COMMAND:  			log.debug("pin management dialog requested via tray menu");  			controller.pinManagement(messages.getLocale()); +			break; -		} else if (HELP_COMMAND.equals(e.getActionCommand())) { +		case HELP_COMMAND:  			log.debug("help page requested via tray menu");  			controller.showHelp(messages.getLocale()); +			break; -		} else { +		default:  			log.error("unknown tray menu command: " + e.getActionCommand());  		}  	} + +	@Override +	public void itemStateChanged(ItemEvent e) { +		log.debug("autostart toggle requested via tray menu"); +		CheckboxMenuItem item = (CheckboxMenuItem) e.getItemSelectable(); +		switch (COMMANDS.valueOf(item.getActionCommand())) { +		case AUTOSTART_COMMAND: +			item.setState((controller.setAutostart(item.getState()))); +			break; + +		default: +			log.error("unknown tray menu command: " + item.getActionCommand()); +		} +	}  } diff --git a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages.properties b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages.properties index 9fe3319a..2d92db03 100644 --- a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages.properties +++ b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages.properties @@ -36,6 +36,8 @@ tray.label.shutdown=Close  tray.label.pin=PIN management  tray.label.help=Help  tray.label.about=About... +tray.label.settings=Settings +tray.label.autostart=Autostart  tray.tooltip.default=CitizenCard  about.frame.title=CitizenCard  about.title=<html>CitizenCard Environment diff --git a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages_de.properties b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages_de.properties index 7b8401d3..44720f5f 100644 --- a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages_de.properties +++ b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/messages_de.properties @@ -36,6 +36,8 @@ tray.label.shutdown=Beenden  tray.label.pin=PIN Verwaltung  tray.label.help=Hilfe  tray.label.about=\u00DCber... +tray.label.settings=Einstellungen +tray.label.autostart=Autostart  tray.tooltip.default=B\u00FCrgerkartenumgebung  about.frame.title=B\u00FCrgerkarte  about.title=<html>B\u00FCrgerkartenumgebung | 
