diff options
Diffstat (limited to 'netx/net/sourceforge/jnlp/services/SingleInstanceLock.java')
-rw-r--r-- | netx/net/sourceforge/jnlp/services/SingleInstanceLock.java | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/services/SingleInstanceLock.java b/netx/net/sourceforge/jnlp/services/SingleInstanceLock.java new file mode 100644 index 0000000..5108642 --- /dev/null +++ b/netx/net/sourceforge/jnlp/services/SingleInstanceLock.java @@ -0,0 +1,194 @@ +// Copyright (C) 2009 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +package net.sourceforge.jnlp.services; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.net.BindException; +import java.net.ServerSocket; + +import net.sourceforge.jnlp.JNLPFile; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.FileUtils; + +/** + * This class represents a Lock for single instance jnlp applications + * + * The lock is per-session, per user. + * + * @author <a href="mailto:[email protected]">Omair Majid</a> + */ +class SingleInstanceLock { + + JNLPFile jnlpFile; + File lockFile = null; + + public static final int INVALID_PORT = Integer.MIN_VALUE; + + int port = INVALID_PORT; + + /** + * Create an object to manage the instance lock for the specified JNLP file. + * + * @param jnlpFile the jnlpfile to create the lock for + */ + public SingleInstanceLock(JNLPFile jnlpFile) { + this.jnlpFile = jnlpFile; + lockFile = getLockFile(); + + } + + /** + * Create/overwrite the instance lock for the jnlp file. + * + * @param localPort the network port for the lock + * @throws IOException on any io problems + */ + public void createWithPort(int localPort) throws IOException { + + BufferedWriter lockFileWriter = new BufferedWriter(new FileWriter(lockFile, false)); + lockFileWriter.write(String.valueOf(localPort)); + lockFileWriter.newLine(); + lockFileWriter.flush(); + lockFileWriter.close(); + + } + + /** + * Returns true if the lock if valid. That is, the lock exists, and port it + * points to is listening for incoming messages. + */ + public boolean isValid() { + return (exists() && getPort() != INVALID_PORT && !isPortFree(getPort())); + } + + /** + * Returns the port in this lock file. + */ + public int getPort() { + if (!exists()) { + return INVALID_PORT; + } + + try { + parseFile(); + } catch (NumberFormatException e) { + port = INVALID_PORT; + } catch (IOException e) { + port = INVALID_PORT; + } + return port; + + } + + /** + * Returns true if the lock file already exists. + */ + private boolean exists() { + return lockFile.exists(); + } + + /** + * Returns true if the port is free. + */ + private boolean isPortFree(int port) { + try { + ServerSocket socket = new ServerSocket(port); + socket.close(); + return true; + } catch (BindException e) { + return false; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Return a file object that represents the lock file. The lock file itself + * may or may not exist. + */ + private File getLockFile() { + File baseDir = new File(JNLPRuntime.LOCKS_DIR); + + if (!baseDir.isDirectory() && !baseDir.mkdirs()) { + throw new RuntimeException(R("RNoLockDir", baseDir)); + } + String lockFileName = getLockFileName(); + File applicationLockFile = new File(baseDir, lockFileName); + return applicationLockFile; + } + + /** + * Returns the name of the lock file. + */ + private String getLockFileName() { + String initialName = ""; + + if (jnlpFile.getSourceLocation() != null) { + initialName = initialName + jnlpFile.getSourceLocation(); + } else { + initialName = initialName + jnlpFile.getFileLocation(); + } + + if (jnlpFile.getFileVersion() != null) { + initialName = initialName + jnlpFile.getFileVersion().toString(); + } + + initialName = initialName + getCurrentDisplay(); + return FileUtils.sanitizeFileName(initialName); + + } + + /** + * Parse the lock file. + * + * @throws NumberFormatException + * @throws IOException + */ + private void parseFile() throws NumberFormatException, IOException { + BufferedReader lockFileReader = new BufferedReader(new FileReader(lockFile)); + int port = Integer.valueOf(lockFileReader.readLine()); + lockFileReader.close(); + this.port = port; + } + + /** + * Returns a string identifying this display. + * + * Implementation note: On systems with X support, this is the DISPLAY + * variable + * + * @return a string that is guaranteed to be not null. + */ + private String getCurrentDisplay() { + String display = System.getenv("DISPLAY"); + return (display == null) ? "" : display; + } + + private static String R(String key) { + return JNLPRuntime.getMessage(key); + } + + private static String R(String key, Object param) { + return JNLPRuntime.getMessage(key, new Object[] { param }); + } + +} |