001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.resources;
017:
018: // J2SE dependencies
019: import java.lang.reflect.Method;
020: import java.nio.ByteBuffer;
021: import java.security.AccessController;
022: import java.security.PrivilegedAction;
023: import java.util.logging.Level;
024: import org.geotools.util.logging.Logging;
025:
026: /**
027: * Utility class for managing memory mapped buffers.
028: *
029: * @since 2.0
030: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/resources/NIOUtilities.java $
031: * @version $Id: NIOUtilities.java 27862 2007-11-12 19:51:19Z desruisseaux $
032: * @author Andres Aimes
033: */
034: public class NIOUtilities {
035: /**
036: * {@code true} if a warning has already been logged.
037: */
038: private static boolean warned = false;
039:
040: /**
041: * Do not allows instantiation of this class.
042: *
043: * @todo This constructor will become private when {@code NIOBufferUtils}
044: * will have been removed.
045: */
046: protected NIOUtilities() {
047: }
048:
049: /**
050: * Really closes a {@code MappedByteBuffer} without the need to wait for garbage
051: * collection. Any problems with closing a buffer on Windows (the problem child in this
052: * case) will be logged as {@code SEVERE} to the logger of the package name. To
053: * force logging of errors, set the System property "org.geotools.io.debugBuffer" to "true".
054: *
055: * @param buffer The buffer to close.
056: * @return true if the operation was successful, false otherwise.
057: *
058: * @see java.nio.MappedByteBuffer
059: */
060: public static boolean clean(final ByteBuffer buffer) {
061: if (buffer == null || !buffer.isDirect()) {
062: return false;
063: }
064: Boolean b = (Boolean) AccessController
065: .doPrivileged(new PrivilegedAction() {
066: public Object run() {
067: Boolean success = Boolean.FALSE;
068: try {
069: Method getCleanerMethod = buffer.getClass()
070: .getMethod("cleaner",
071: (Class[]) null);
072: getCleanerMethod.setAccessible(true);
073: Object cleaner = getCleanerMethod.invoke(
074: buffer, (Object[]) null);
075: Method clean = cleaner.getClass()
076: .getMethod("clean", (Class[]) null);
077: clean.invoke(cleaner, (Object[]) null);
078: success = Boolean.TRUE;
079: } catch (Exception e) {
080: // This really is a show stopper on windows
081: if (isLoggable()) {
082: log(e, buffer);
083: }
084: }
085: return success;
086: }
087: });
088:
089: return b.booleanValue();
090: }
091:
092: /**
093: * Check if a warning message should be logged.
094: */
095: private static synchronized boolean isLoggable() {
096: try {
097: return !warned
098: && (Boolean
099: .getBoolean("org.geotools.io.debugBuffer") || System
100: .getProperty("os.name").indexOf("Windows") >= 0);
101: } catch (SecurityException exception) {
102: // The utilities may be running in an Applet, in which case we
103: // can't read properties. Assumes we are not in debugging mode.
104: return false;
105: }
106: }
107:
108: /**
109: * Log a warning message.
110: */
111: private static synchronized void log(final Exception e,
112: final ByteBuffer buffer) {
113: warned = true;
114: String message = "Error attempting to close a mapped byte buffer : "
115: + buffer.getClass().getName()
116: + "\n JVM : "
117: + System.getProperty("java.version")
118: + ' '
119: + System.getProperty("java.vendor");
120: Logging.getLogger("org.geotools.io").log(Level.SEVERE, message,
121: e);
122: }
123: }
|