/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvmstat.perfdata.monitor.protocol.local;
import java.io.File;
import java.io.FilenameFilter;
Class to provide translations from the local Vm Identifier
name space into the file system name space and vice-versa.
Provides a factory for creating a File object to the backing
store file for instrumentation shared memory region for a JVM
identified by its Local Java Virtual Machine Identifier, or
lvmid.
Author: Brian Doherty See Also: Since: 1.5
/**
* Class to provide translations from the local Vm Identifier
* name space into the file system name space and vice-versa.
* <p>
* Provides a factory for creating a File object to the backing
* store file for instrumentation shared memory region for a JVM
* identified by its Local Java Virtual Machine Identifier, or
* <em>lvmid</em>.
*
* @author Brian Doherty
* @since 1.5
* @see java.io.File
*/
public class PerfDataFile {
private PerfDataFile() { };
The name of the of the system dependent temporary directory
/**
* The name of the of the system dependent temporary directory
*/
public static final String tmpDirName;
The file name prefix for PerfData shared memory files.
This prefix must be kept in sync with the prefix used by the JVM.
/**
* The file name prefix for PerfData shared memory files.
* <p>
* This prefix must be kept in sync with the prefix used by the JVM.
*/
public static final String dirNamePrefix = "hsperfdata_";
The directory name pattern for the user directories.
/**
* The directory name pattern for the user directories.
*/
public static final String userDirNamePattern = "hsperfdata_\\S*";
The file name pattern for PerfData shared memory files.
This pattern must be kept in synch with the file name pattern
used by the 1.4.2 and later HotSpot JVM.
/**
* The file name pattern for PerfData shared memory files.
* <p>
* This pattern must be kept in synch with the file name pattern
* used by the 1.4.2 and later HotSpot JVM.
*/
public static final String fileNamePattern = "^[0-9]+$";
The file name pattern for 1.4.1 PerfData shared memory files.
This pattern must be kept in synch with the file name pattern
used by the 1.4.1 HotSpot JVM.
/**
* The file name pattern for 1.4.1 PerfData shared memory files.
* <p>
* This pattern must be kept in synch with the file name pattern
* used by the 1.4.1 HotSpot JVM.
*/
public static final String tmpFileNamePattern =
"^hsperfdata_[0-9]+(_[1-2]+)?$";
Get a File object for the instrumentation backing store file
for the JVM identified by the given local Vm Identifier.
This method looks for the most up to date backing store file for
the given lvmid. It will search all the user specific
directories in the temporary directory for the host operating
system, which may be influenced by platform specific environment
variables.
Params: - lvmid – the local Java Virtual Machine Identifier for the target
See Also: Returns: File - a File object to the backing store file for the named
shared memory region of the target JVM.
/**
* Get a File object for the instrumentation backing store file
* for the JVM identified by the given local Vm Identifier.
* <p>
* This method looks for the most up to date backing store file for
* the given <tt>lvmid</tt>. It will search all the user specific
* directories in the temporary directory for the host operating
* system, which may be influenced by platform specific environment
* variables.
*
* @param lvmid the local Java Virtual Machine Identifier for the target
* @return File - a File object to the backing store file for the named
* shared memory region of the target JVM.
* @see java.io.File
* @see #getTempDirectory()
*/
public static File getFile(int lvmid) {
if (lvmid == 0) {
/*
* lvmid == 0 is used to indicate the current Java Virtual Machine.
* If the SDK provided an API to get a unique Java Virtual Machine
* identifier, then a filename could be constructed with that
* identifier. In absence of such an api, return null.
*/
return null;
}
/*
* iterate over all files in all directories in tmpDirName that
* match the file name patterns.
*/
File tmpDir = new File(tmpDirName);
String[] files = tmpDir.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
if (!name.startsWith(dirNamePrefix)) {
return false;
}
File candidate = new File(dir, name);
return ((candidate.isDirectory() || candidate.isFile())
&& candidate.canRead());
}
});
long newestTime = 0;
File newest = null;
for (int i = 0; i < files.length; i++) {
File f = new File(tmpDirName + files[i]);
File candidate = null;
if (f.exists() && f.isDirectory()) {
/*
* found a directory matching the name patterns. This
* is a 1.4.2 hsperfdata_<user> directory. Check for
* file named <lvmid> in that directory
*/
String name = Integer.toString(lvmid);
candidate = new File(f.getName(), name);
} else if (f.exists() && f.isFile()) {
/*
* found a file matching the name patterns. This
* is a 1.4.1 hsperfdata_<lvmid> file.
*/
candidate = f;
} else {
// unexpected - let conditional below filter this one out
candidate = f;
}
if (candidate.exists() && candidate.isFile()
&& candidate.canRead()) {
long modTime = candidate.lastModified();
if (modTime >= newestTime) {
newestTime = modTime;
newest = candidate;
}
}
}
return newest;
}
Return the File object for the backing store file for the specified Java
Virtual Machine.
This method looks for the most up to date backing store file for
the JVM identified by the given user name and lvmid. The directory
searched is the temporary directory for the host operating system,
which may be influenced by environment variables.
Params: - user – the user name
- lvmid – the local Java Virtual Machine Identifier for the target
See Also: Returns: File - a File object to the backing store file for the named
shared memory region of the target JVM.
/**
* Return the File object for the backing store file for the specified Java
* Virtual Machine.
* <p>
* This method looks for the most up to date backing store file for
* the JVM identified by the given user name and lvmid. The directory
* searched is the temporary directory for the host operating system,
* which may be influenced by environment variables.
*
* @param user the user name
* @param lvmid the local Java Virtual Machine Identifier for the target
* @return File - a File object to the backing store file for the named
* shared memory region of the target JVM.
* @see java.io.File
* @see #getTempDirectory()
*/
public static File getFile(String user, int lvmid) {
if (lvmid == 0) {
/*
* lvmid == 0 is used to indicate the current Java Virtual Machine.
* If the SDK provided an API to get a unique Java Virtual Machine
* identifier, then a filename could be constructed with that
* identifier. In absence of such an api, return null.
*/
return null;
}
// first try for 1.4.2 and later JVMs
String basename = getTempDirectory(user) + Integer.toString(lvmid);
File f = new File(basename);
if (f.exists() && f.isFile() && f.canRead()) {
return f;
}
// No hit on 1.4.2 JVMs, try 1.4.1 files
long newestTime = 0;
File newest = null;
for (int i = 0; i < 2; i++) {
if (i == 0) {
basename = getTempDirectory() + Integer.toString(lvmid);
} else {
basename = getTempDirectory() + Integer.toString(lvmid)
+ Integer.toString(i);
}
f = new File(basename);
if (f.exists() && f.isFile() && f.canRead()) {
long modTime = f.lastModified();
if (modTime >= newestTime) {
newestTime = modTime;
newest = f;
}
}
}
return newest;
}
Method to extract a local Java Virtual Machine Identifier from the
file name of the given File object.
Params: - file – A File object representing the name of a
shared memory region for a target JVM
Throws: - IllegalArgumentException – Thrown if the file name
does not conform to the expected pattern
Returns: int - the local Java Virtual Machine Identifier for the target
associated with the file
/**
* Method to extract a local Java Virtual Machine Identifier from the
* file name of the given File object.
*
* @param file A File object representing the name of a
* shared memory region for a target JVM
* @return int - the local Java Virtual Machine Identifier for the target
* associated with the file
* @throws java.lang.IllegalArgumentException Thrown if the file name
* does not conform to the expected pattern
*/
public static int getLocalVmId(File file) {
try {
// try 1.4.2 and later format first
return Integer.parseInt(file.getName());
} catch (NumberFormatException e) { }
// now try the 1.4.1 format
String name = file.getName();
if (name.startsWith(dirNamePrefix)) {
int first = name.indexOf('_');
int last = name.lastIndexOf('_');
try {
if (first == last) {
return Integer.parseInt(name.substring(first + 1));
} else {
return Integer.parseInt(name.substring(first + 1, last));
}
} catch (NumberFormatException e) { }
}
throw new IllegalArgumentException("file name does not match pattern");
}
Return the name of the temporary directory being searched for
HotSpot PerfData backing store files.
This method generally returns the value of the java.io.tmpdir
property. However, on some platforms it may return a different
directory, as the JVM implementation may store the PerfData backing
store files in a different directory for performance reasons.
Returns: String - the name of the temporary directory.
/**
* Return the name of the temporary directory being searched for
* HotSpot PerfData backing store files.
* <p>
* This method generally returns the value of the java.io.tmpdir
* property. However, on some platforms it may return a different
* directory, as the JVM implementation may store the PerfData backing
* store files in a different directory for performance reasons.
*
* @return String - the name of the temporary directory.
*/
public static String getTempDirectory() {
return tmpDirName;
}
Return the name of the temporary directory to be searched
for HotSpot PerfData backing store files for a given user.
This method generally returns the name of a subdirectory of
the directory indicated in the java.io.tmpdir property. However,
on some platforms it may return a different directory, as the
JVM implementation may store the PerfData backing store files
in a different directory for performance reasons.
Returns: String - the name of the temporary directory.
/**
* Return the name of the temporary directory to be searched
* for HotSpot PerfData backing store files for a given user.
* <p>
* This method generally returns the name of a subdirectory of
* the directory indicated in the java.io.tmpdir property. However,
* on some platforms it may return a different directory, as the
* JVM implementation may store the PerfData backing store files
* in a different directory for performance reasons.
*
* @return String - the name of the temporary directory.
*/
public static String getTempDirectory(String user) {
return tmpDirName + dirNamePrefix + user + File.separator;
}
static {
/*
* For this to work, the target VM and this code need to use
* the same directory. Instead of guessing which directory the
* VM is using, we will ask.
*/
String tmpdir = sun.misc.VMSupport.getVMTemporaryDirectory();
/*
* Assure that the string returned has a trailing File.separator
* character. This check was added because the Linux implementation
* changed such that the java.io.tmpdir string no longer terminates
* with a File.separator character.
*/
if (tmpdir.lastIndexOf(File.separator) != (tmpdir.length()-1)) {
tmpdir = tmpdir + File.separator;
}
tmpDirName = tmpdir;
}
}