aboutsummaryrefslogtreecommitdiffstats
path: root/netx/net/sourceforge/jnlp/services/SingleInstanceLock.java
diff options
context:
space:
mode:
Diffstat (limited to 'netx/net/sourceforge/jnlp/services/SingleInstanceLock.java')
-rw-r--r--netx/net/sourceforge/jnlp/services/SingleInstanceLock.java194
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 });
+ }
+
+}