[Arakhnę-Dev] [117] Release 2.0. |
[ Thread Index |
Date Index
| More arakhne.org/dev Archives
]
Revision: 117
Author: galland
Date: 2010-01-21 09:29:52 +0100 (Thu, 21 Jan 2010)
Log Message:
-----------
Release 2.0.
Added Paths:
-----------
tags/afc-2.0/
tags/afc-2.0/arakhneLog4J/
tags/afc-2.0/arakhneLog4J/pom.xml
tags/afc-2.0/arakhneLog4J/src/
tags/afc-2.0/arakhneLog4J/src/main/
tags/afc-2.0/arakhneLog4J/src/main/java/
tags/afc-2.0/arakhneLog4J/src/main/java/org/
tags/afc-2.0/arakhneLog4J/src/main/java/org/arakhne/
tags/afc-2.0/arakhneLog4J/src/main/java/org/arakhne/logging/
tags/afc-2.0/arakhneLog4J/src/main/java/org/arakhne/logging/ApacheLogger.java
tags/afc-2.0/arakhneLogger/
tags/afc-2.0/arakhneLogger/pom.xml
tags/afc-2.0/arakhneLogger/src/
tags/afc-2.0/arakhneLogger/src/main/
tags/afc-2.0/arakhneLogger/src/main/java/
tags/afc-2.0/arakhneLogger/src/main/java/org/
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractLogger.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractPrintStreamLogger.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractStandAloneLogger.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/ConsoleLogger.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/FileLogger.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LogLevel.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/Logger.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEvent.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEventListener.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggingSystem.java
tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/SunLogger.java
tags/afc-2.0/arakhneLogger/src/main/resources/
tags/afc-2.0/arakhneLogger/src/main/resources/org/
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger.properties
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_de.properties
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_es.properties
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_fr.properties
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_it.properties
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_nl.properties
tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_pt.properties
tags/afc-2.0/arakhneRefs/
tags/afc-2.0/arakhneRefs/pom.xml
tags/afc-2.0/arakhneRefs/src/
tags/afc-2.0/arakhneRefs/src/main/
tags/afc-2.0/arakhneRefs/src/main/java/
tags/afc-2.0/arakhneRefs/src/main/java/org/
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableSoftReference.java
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableWeakReference.java
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ReferenceListener.java
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java
tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java
tags/afc-2.0/arakhneRefs/src/main/resources/
tags/afc-2.0/arakhneRefs/src/main/resources/AUTHORS
tags/afc-2.0/arakhneRefs/src/main/resources/COPYING
tags/afc-2.0/arakhneRefs/src/main/resources/Changelog
tags/afc-2.0/arakhneRefs/src/main/resources/VERSION
tags/afc-2.0/arakhneRefs/src/test/
tags/afc-2.0/arakhneRefs/src/test/java/
tags/afc-2.0/arakhneRefs/src/test/java/org/
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractRepeatedTest.java
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractTestCase.java
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/RepeatableTest.java
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakArrayListTest.java
tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
tags/afc-2.0/arakhneVmutils/
tags/afc-2.0/arakhneVmutils/bin.xml
tags/afc-2.0/arakhneVmutils/java/
tags/afc-2.0/arakhneVmutils/java/pom.xml
tags/afc-2.0/arakhneVmutils/java/src/
tags/afc-2.0/arakhneVmutils/java/src/main/
tags/afc-2.0/arakhneVmutils/java/src/main/java/
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/AutoboxingUtil.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Caller.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLStreamHandlerFactory.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileSystem.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/LibraryLoader.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/MACNumber.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystem.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLConnection.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandler.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandlerFactory.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Resources.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java
tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/VMCommandLine.java
tags/afc-2.0/arakhneVmutils/java/src/main/resources/
tags/afc-2.0/arakhneVmutils/java/src/main/resources/AUTHORS
tags/afc-2.0/arakhneVmutils/java/src/main/resources/COPYING
tags/afc-2.0/arakhneVmutils/java/src/main/resources/Changelog
tags/afc-2.0/arakhneVmutils/java/src/main/resources/VERSION
tags/afc-2.0/arakhneVmutils/java/src/test/
tags/afc-2.0/arakhneVmutils/java/src/test/java/
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileSystemTest.java
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourceURLConnectionTest.java
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourcesTest.java
tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java
tags/afc-2.0/arakhneVmutils/java/src/test/resources/
tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/
tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/arakhne/
tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/arakhne/vmutil/
tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/arakhne/vmutil/test.txt
tags/afc-2.0/arakhneVmutils/native/
tags/afc-2.0/arakhneVmutils/native/josuuid/
tags/afc-2.0/arakhneVmutils/native/josuuid/linux32/
tags/afc-2.0/arakhneVmutils/native/josuuid/linux32/pom.xml
tags/afc-2.0/arakhneVmutils/native/josuuid/linux64/
tags/afc-2.0/arakhneVmutils/native/josuuid/linux64/pom.xml
tags/afc-2.0/arakhneVmutils/native/josuuid/mingw/
tags/afc-2.0/arakhneVmutils/native/josuuid/mingw/pom.xml
tags/afc-2.0/arakhneVmutils/native/josuuid/pom.xml
tags/afc-2.0/arakhneVmutils/native/josuuid/src/
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/OperatingSystemJNI.cpp
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.cpp
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.h
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/osmacro.h
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.cpp
tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.h
tags/afc-2.0/arakhneVmutils/native/josuuid/src/test/
tags/afc-2.0/arakhneVmutils/native/pom.xml
tags/afc-2.0/arakhneVmutils/pom.xml
tags/afc-2.0/pom.xml
Added: tags/afc-2.0/arakhneLog4J/pom.xml
===================================================================
--- tags/afc-2.0/arakhneLog4J/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneLog4J/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>afc</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>2.0</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneLog4J</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <name>${pom.artifactId}</name>
+ <url>http://www.arakhne.org/arakhneLogger/</url>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneLogger</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ </dependency>
+ </dependencies>
+
+</project>
Added: tags/afc-2.0/arakhneLog4J/src/main/java/org/arakhne/logging/ApacheLogger.java
===================================================================
--- tags/afc-2.0/arakhneLog4J/src/main/java/org/arakhne/logging/ApacheLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLog4J/src/main/java/org/arakhne/logging/ApacheLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import org.apache.log4j.Level;
+
+/**
+ * This class provides the concrete implementation of the <code>Logger</code>
+ * interface. This impl is based on the Apache's Logging Facade for Java, aka.
+ * Log4J.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public class ApacheLogger extends AbstractLogger {
+
+ private final org.apache.log4j.Logger bindedLogger;
+
+ /**
+ * Create an unamed logger based of Apache's logging system.
+ */
+ public ApacheLogger() {
+ this.bindedLogger = org.apache.log4j.Logger.getRootLogger();
+ this.bindedLogger.setLevel(Level.ALL);
+ }
+
+ /**
+ * Create a named logger based of Apache's logging system.
+ *
+ * @param name is the name of the logger.
+ */
+ public ApacheLogger(String name) {
+ this.bindedLogger = org.apache.log4j.Logger.getLogger(name);
+ this.bindedLogger.setLevel(toApacheLevel(getLogLevel()));
+ }
+
+// **************************************************************************************//
+
+ /** Translate a logging level into the same thing for Apache's logging system.
+ *
+ * @param level is the level to translate
+ * @return the Sun's level
+ */
+ protected Level toApacheLevel(LogLevel level) {
+ switch(level) {
+ case NONE:
+ return Level.OFF;
+ case ERROR:
+ return Level.ERROR;
+ case WARNING:
+ return Level.WARN;
+ case INFO:
+ return Level.INFO;
+ case DEBUG:
+ return Level.DEBUG;
+ }
+ return Level.OFF;
+ }
+
+ /** {@InheritDoc}
+ */
+ @Override
+ public void log(Object source, LogLevel level, String msg) {
+ this.bindedLogger.log(toApacheLevel(level),msg);
+ fireLoggerEvent(source, level, msg);
+ }
+
+ /** {@InheritDoc}
+ */
+ public void log(Object source, LogLevel level, String msg, Throwable exception) {
+ this.bindedLogger.log(toApacheLevel(level),msg,exception);
+ fireLoggerEvent(source, level, msg);
+ }
+
+
+// **************************************************************************************//
+
+ /** {@InheritDoc}
+ *
+ * @return {@InheritDoc}
+ */
+ public String getName() {
+ return this.bindedLogger.getName();
+ }
+
+ /** Set the minimum log level.
+ *
+ * @param level
+ */
+ @Override
+ public void setLogLevel(LogLevel level) {
+ super.setLogLevel(level);
+ this.bindedLogger.setLevel(toApacheLevel(level));
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/pom.xml
===================================================================
--- tags/afc-2.0/arakhneLogger/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneLogger/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>afc</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>2.0</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneLogger</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2</version>
+ <name>${pom.artifactId}</name>
+ <url>http://www.arakhne.org/arakhneLogger/</url>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+</project>
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractLogger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,295 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the base for a concrete implementation of the <code>Logger</code>
+ * interface.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public abstract class AbstractLogger implements Logger {
+
+ private LogLevel minLevel;
+ private transient List<LoggerEventListener> listeners = null;
+
+ /**
+ */
+ public AbstractLogger() {
+ this.minLevel = null;
+ }
+
+ /** Check if logging is allowed.
+ *
+ * @param requestedLevel is the level to check.
+ * @return <code>true</code> if logging is allowed, <code>false</code> otherwise
+ */
+ protected final boolean isLoggableFor(LogLevel requestedLevel) {
+ return requestedLevel.hasHigherPriority(getLogLevel());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setLogLevel(LogLevel level) {
+ this.minLevel = level;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final LogLevel getLogLevel() {
+ if (this.minLevel==null) return LoggingSystem.getLoggingSystem().getDefaultLogLevel();
+ return this.minLevel;
+ }
+
+ /** {@InheritDoc}
+ *
+ * @param arg0 {@InheritDoc}
+ * @param arg1 {@InheritDoc}
+ */
+ @Deprecated
+ public final void debug(String arg0, Throwable arg1) {
+ log(this,LogLevel.DEBUG,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void debug(String arg0) {
+ log(LogLevel.DEBUG,arg0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void error(String arg0, Throwable arg1) {
+ log(this,LogLevel.ERROR,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void error(String arg0) {
+ log(this,LogLevel.ERROR,arg0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void info(String arg0, Throwable arg1) {
+ log(this,LogLevel.INFO,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void info(String arg0) {
+ log(this,LogLevel.INFO,arg0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void warn(String arg0, Throwable arg1) {
+ log(this,LogLevel.WARNING,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ public final void warn(String arg0) {
+ log(this,LogLevel.WARNING,arg0);
+ }
+
+ /** {@InheritDoc}
+ *
+ * @param level {@InheritDoc}
+ * @param msg {@InheritDoc}
+ */
+ @Deprecated
+ public final void log(LogLevel level, String msg) {
+ log(this, level, msg, null);
+ }
+
+ /** {@InheritDoc}
+ */
+ @Deprecated
+ public final void log(LogLevel level, String msg, Throwable exception) {
+ log(this,level,msg,exception);
+ }
+
+ /** {@InheritDoc}
+ */
+ public final void debug(Object source, String arg0, Throwable arg1) {
+ log(source,LogLevel.DEBUG,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void debug(Object source, String arg0) {
+ log(source, LogLevel.DEBUG,arg0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void error(Object source, String arg0, Throwable arg1) {
+ log(source,LogLevel.ERROR,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void error(Object source, String arg0) {
+ log(source,LogLevel.ERROR,arg0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void info(Object source, String arg0, Throwable arg1) {
+ log(source,LogLevel.INFO,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void info(Object source, String arg0) {
+ log(source,LogLevel.INFO,arg0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void warn(Object source, String arg0, Throwable arg1) {
+ log(source,LogLevel.WARNING,arg0,arg1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void warn(Object source, String arg0) {
+ log(source,LogLevel.WARNING,arg0);
+ }
+
+ /** {@InheritDoc}
+ */
+ public void log(Object source, LogLevel level, String msg) {
+ log(source, level, msg, null);
+ }
+
+ /** {@InheritDoc}
+ *
+ * @return {@InheritDoc}
+ */
+ public boolean isDebugEnabled() {
+ return isLoggableFor(LogLevel.DEBUG);
+ }
+
+ /** {@InheritDoc}
+ *
+ * @return {@InheritDoc}
+ */
+ public boolean isErrorEnabled() {
+ return isLoggableFor(LogLevel.ERROR);
+ }
+
+ /** {@InheritDoc}
+ *
+ * @return {@InheritDoc}
+ */
+ public boolean isInfoEnabled() {
+ return isLoggableFor(LogLevel.INFO);
+ }
+
+ /** {@InheritDoc}
+ *
+ * @return {@InheritDoc}
+ */
+ public boolean isWarnEnabled() {
+ return isLoggableFor(LogLevel.WARNING);
+ }
+
+ /** Add listener on logger events.
+ *
+ * @param listener
+ */
+ public final void addLoggerEventListener(LoggerEventListener listener) {
+ if (this.listeners==null) {
+ this.listeners = new ArrayList<LoggerEventListener>();
+ }
+ this.listeners.add(listener);
+ }
+
+ /** Remove listener on logger events.
+ *
+ * @param listener
+ */
+ public void removeLoggerEventListener(LoggerEventListener listener) {
+ if (this.listeners!=null) {
+ this.listeners.remove(listener);
+ if (this.listeners.isEmpty())
+ this.listeners = null;
+ }
+ }
+
+ /** Notify the logger event listeners.
+ *
+ * @param source is the object which has log the message.
+ * @param level is the level of the message
+ * @param message is the text of the message.
+ */
+ protected final void fireLoggerEvent(Object source, LogLevel level, String message) {
+ fireLoggerEvent(source, level, message, null);
+ }
+
+ /** Notify the logger event listeners.
+ *
+ * @param source is the object which has log the message.
+ * @param level is the level of the message
+ * @param message is the text of the message.
+ * @param exception is the exception associated to the message.
+ */
+ protected final void fireLoggerEvent(Object source, LogLevel level, String message, Throwable exception) {
+ LoggerEvent event = new LoggerEvent(source, this, level, message, exception);
+ if (this.listeners!=null) {
+ for(LoggerEventListener listener : this.listeners) {
+ listener.onLoggedEvent(event);
+ }
+ }
+ LoggingSystem.getLoggingSystem().fireLoggerEvent(event);
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractPrintStreamLogger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractPrintStreamLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractPrintStreamLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,96 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.io.PrintStream;
+
+/**
+ * This class provides the base for a concrete implementation of the <code>Logger</code>
+ * interface. This logger impl contains the minimal knowledge required to implement
+ * loggers which are writing inside a print stream.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public abstract class AbstractPrintStreamLogger extends AbstractStandAloneLogger {
+
+ /** Output print stream for anomalies.
+ */
+ protected final PrintStream anomalyStream;
+
+ /** Output print stream for messages.
+ */
+ protected final PrintStream noticeStream;
+
+ /**
+ * Unamed Logger on system console.
+ *
+ * @param anomalyStream is the output stream inside which anomaly logs will be put.
+ * @param noticeStream is the output stream inside which notice logs will be put.
+ */
+ public AbstractPrintStreamLogger(PrintStream anomalyStream, PrintStream noticeStream) {
+ this.anomalyStream = anomalyStream;
+ this.noticeStream = noticeStream;
+ }
+
+ /**
+ * Named Logger on system console.
+ *
+ * @param anomalyStream is the output stream inside which anomaly logs will be put.
+ * @param noticeStream is the output stream inside which notice logs will be put.
+ * @param name is the name of the logger.
+ */
+ public AbstractPrintStreamLogger(PrintStream anomalyStream, PrintStream noticeStream, String name) {
+ super(name);
+ this.anomalyStream = anomalyStream;
+ this.noticeStream = noticeStream;
+ }
+
+ /** {@InheritDoc}
+ */
+ public void log(Object source, LogLevel level, String msg, Throwable exception) {
+ if (isLoggableFor(level)) {
+
+ StringBuffer buffer = new StringBuffer();
+
+ if (this.name!=null) {
+ buffer.append("["); //$NON-NLS-1$
+ buffer.append(this.name);
+ buffer.append("] - "); //$NON-NLS-1$
+ }
+ buffer.append(getLocalizedString(level));
+ buffer.append(": "); //$NON-NLS-1$
+ buffer.append(msg);
+
+ PrintStream ps = level.isAnomalyLevel() ? this.anomalyStream : this.noticeStream;
+
+ ps.println(buffer.toString());
+
+ if (exception!=null) {
+ exception.printStackTrace(ps);
+ }
+
+ fireLoggerEvent(source, level, msg);
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractStandAloneLogger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractStandAloneLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/AbstractStandAloneLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class provides the base for a concrete implementation of the <code>Logger</code>
+ * interface. This logger impl is not wrapped to a third-party logger (Sun nor Apache
+ * for example). It contains the minimal knowledge required to implement
+ * not-wrapped loggers.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public abstract class AbstractStandAloneLogger extends AbstractLogger {
+
+ private static String errorLabel = null;
+ private static String warningLabel = null;
+ private static String infoLabel = null;
+ private static String debugLabel = null;
+
+ /** Replies the label which is corresponding to the given log level.
+ *
+ * @param level
+ * @return the localized label which is corresponding to the given log level.
+ */
+ protected static String getLocalizedString(LogLevel level) {
+ switch (level) {
+ case NONE:
+ return null;
+ case DEBUG:
+ if (debugLabel!=null) return debugLabel;
+ break;
+ case WARNING:
+ if (warningLabel!=null) return warningLabel;
+ break;
+ case ERROR:
+ if (errorLabel!=null) return errorLabel;
+ break;
+ case INFO:
+ if (infoLabel!=null) return infoLabel;
+ break;
+ }
+
+ String name = level.name().toUpperCase();
+
+ try {
+ ResourceBundle resource = ResourceBundle.getBundle(AbstractStandAloneLogger.class.getCanonicalName());
+ String str = resource.getString(name);
+ if ((str!=null)&&(!"".equals(str))) //$NON-NLS-1$
+ name = str;
+ }
+ catch (MissingResourceException exep) {
+ //
+ }
+
+ switch (level) {
+ case NONE:
+ return null;
+ case DEBUG:
+ debugLabel = name;
+ break;
+ case WARNING:
+ warningLabel = name;
+ break;
+ case ERROR:
+ errorLabel = name;
+ break;
+ case INFO:
+ infoLabel = name;
+ break;
+ }
+
+ return name;
+ }
+
+ /** Name of this logger.
+ */
+ protected final String name;
+
+ /**
+ * Unamed Logger on system console.
+ */
+ public AbstractStandAloneLogger() {
+ this.name = null;
+ }
+
+ /**
+ * Named Logger on system console.
+ *
+ * @param name is the name of the logger.
+ */
+ public AbstractStandAloneLogger(String name) {
+ this.name = name;
+ }
+
+ /** {@InheritDoc}
+ */
+ public String getName() {
+ return this.name;
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/ConsoleLogger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/ConsoleLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/ConsoleLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+/**
+ * This class provides the concrete implementation of the <code>Logger</code>
+ * interface. This impl is displaying on the standard output.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public class ConsoleLogger extends AbstractPrintStreamLogger {
+
+ /**
+ * Unamed Logger on system console.
+ */
+ public ConsoleLogger() {
+ super(System.err, System.out);
+ }
+
+ /**
+ * Named Logger on system console.
+ *
+ * @param name is the name of the logger.
+ */
+ public ConsoleLogger(String name) {
+ super(System.err, System.out, name);
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/FileLogger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/FileLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/FileLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+/**
+ * This class provides the concrete implementation of the <code>Logger</code>
+ * interface. This impl is writting inside a file.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public class FileLogger extends AbstractPrintStreamLogger {
+
+ private final File logFile;
+
+ /**
+ * Unamed Logger on system console.
+ *
+ * @param logFile is the log file to write inside.
+ * @throws IOException when error on log file opening.
+ */
+ public FileLogger(File logFile) throws IOException {
+ this(logFile, new PrintStream(new FileOutputStream(logFile)));
+ }
+
+ /**
+ * Named Logger on system console.
+ *
+ * @param logFile is the log file to write inside.
+ * @param name is the name of the logger.
+ * @throws IOException when error on log file opening.
+ */
+ public FileLogger(File logFile, String name) throws IOException {
+ this(logFile, new PrintStream(new FileOutputStream(logFile)), name);
+ }
+
+ private FileLogger(File logFile, PrintStream logStream) {
+ super(logStream, logStream);
+ this.logFile = logFile;
+ }
+
+ private FileLogger(File logFile, PrintStream logStream, String name) {
+ super(logStream, logStream, name);
+ this.logFile = logFile;
+ }
+
+ /** Replies the log file which is written by this logger.
+ *
+ * @return the log file, never <code>null</code>
+ */
+ public File getLogFile() {
+ return this.logFile;
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LogLevel.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LogLevel.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LogLevel.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+/**
+ * The enum describing the various available log levels.
+ *
+ * @author Nicolas GAUD <gaud@xxxxxxxxxxx>
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public enum LogLevel {
+ /**
+ * No logging.
+ */
+ NONE,
+ /**
+ * Error message Level.
+ */
+ ERROR,
+ /**
+ * Warning message Level.
+ */
+ WARNING,
+ /**
+ * Information message Level.
+ */
+ INFO,
+ /**
+ * Debug message Level.
+ */
+ DEBUG;
+
+ /** Check if logging is allowed.
+ * This function check if the current log level has a priority
+ * greater or equals to the given log level.
+ *
+ * @param referenceLogLevel is the level to check.
+ * @return <code>true</code> if logging is allowed, <code>false</code> otherwise
+ */
+ public boolean hasHigherPriority(LogLevel referenceLogLevel) {
+ return ordinal()>0 && ordinal()<=referenceLogLevel.ordinal();
+ }
+
+ /** Replies if this log level is for anomalies.
+ *
+ * @return <code>true</code> if this log level is an error or a warning,
+ * otherwise <code>false</code>.
+ */
+ public boolean isAnomalyLevel() {
+ return this==ERROR || this==WARNING;
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/Logger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/Logger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/Logger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,302 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+/**
+ * The main user interface to logging.
+ * This interface provides classic method use to log
+ * string or status at various level.
+ * These level are described in the <code>LogLevel</code> Enum;
+ *
+ * @author Nicolas GAUD <gaud@xxxxxxxxxxx>
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see LogLevel
+ */
+public interface Logger {
+
+ /**
+ * Return the name of this <code>Logger</code> instance.
+ *
+ * @return the name of this <code>Logger</code> instance.
+ */
+ public String getName();
+
+ /**
+ * Is the logger instance enabled for the DEBUG level?
+ *
+ * @return <code>true</code> if this Logger is enabled for the DEBUG level,
+ * <code>false</code> otherwise.
+ */
+ public boolean isDebugEnabled();
+
+ /**
+ * Log the specified message at the specified level
+ *
+ * @param level - the log level
+ * @param msg - the message to log
+ * @deprecated see {@link #log(Object, LogLevel, String)}
+ */
+ @Deprecated
+ public void log(LogLevel level, String msg);
+
+ /**
+ * Log the specified message at the specified level
+ *
+ * @param source - the object which send this log
+ * @param level - the log level
+ * @param msg - the message to log
+ * @since 1.2
+ */
+ public void log(Object source, LogLevel level, String msg);
+
+ /**
+ * Log the specified message at the specified level
+ *
+ * @param level - the log level
+ * @param msg - the message to log
+ * @param exception - the exception cause of the log message
+ * @deprecated see {@link #log(Object, LogLevel, String, Throwable)}
+ */
+ @Deprecated
+ public void log(LogLevel level, String msg, Throwable exception);
+
+ /**
+ * Log the specified message at the specified level
+ *
+ * @param source - the object which send this log
+ * @param level - the log level
+ * @param msg - the message to log
+ * @param exception - the exception cause of the log message
+ * @since 1.2
+ */
+ public void log(Object source, LogLevel level, String msg, Throwable exception);
+
+ /**
+ * Log a message at the DEBUG level.
+ *
+ * @param msg the message string to be logged
+ * @deprecated see {@link #debug(Object, String)}
+ */
+ @Deprecated
+ public void debug(String msg);
+
+ /**
+ * Log a message at the DEBUG level.
+ *
+ * @param source - the object which send this log
+ * @param msg the message string to be logged
+ * @since 1.2
+ */
+ public void debug(Object source, String msg);
+
+ /**
+ * Log an exception (throwable) at the DEBUG level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @deprecated see {@link #debug(Object, String, Throwable)}
+ */
+ @Deprecated
+ public void debug(String msg, Throwable t);
+
+ /**
+ * Log an exception (throwable) at the DEBUG level with an
+ * accompanying message.
+ *
+ * @param source - the object which send this log
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 1.2
+ */
+ public void debug(Object source, String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the INFO level?
+ *
+ * @return <code>true</code> if this Logger is enabled for the INFO level,
+ * <code>false</code> otherwise.
+ */
+ public boolean isInfoEnabled();
+
+
+ /**
+ * Log a message at the INFO level.
+ *
+ * @param msg the message string to be logged
+ * @deprecated see {@link #info(Object, String)}
+ */
+ @Deprecated
+ public void info(String msg);
+
+ /**
+ * Log a message at the INFO level.
+ *
+ * @param source - the object which send this log
+ * @param msg the message string to be logged
+ * @since 1.2
+ */
+ public void info(Object source, String msg);
+
+ /**
+ * Log an exception (throwable) at the INFO level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @deprecated see {@link #info(Object, String, Throwable)}
+ */
+ @Deprecated
+ public void info(String msg, Throwable t);
+
+ /**
+ * Log an exception (throwable) at the INFO level with an
+ * accompanying message.
+ *
+ * @param source - the object which send this log
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 1.2
+ */
+ public void info(Object source, String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the WARN level?
+ *
+ * @return <code>true</code> if this Logger is enabled for the WARN level,
+ * <code>false</code> otherwise.
+ */
+ public boolean isWarnEnabled();
+
+ /**
+ * Log a message at the WARN level.
+ *
+ * @param msg the message string to be logged
+ * @deprecated see {@link #warn(Object, String)}
+ */
+ @Deprecated
+ public void warn(String msg);
+
+ /**
+ * Log a message at the WARN level.
+ *
+ * @param source - the object which send this log
+ * @param msg the message string to be logged
+ * @since 1.2
+ */
+ public void warn(Object source, String msg);
+
+ /**
+ * Log an exception (throwable) at the WARN level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @deprecated see {@link #warn(Object, String, Throwable)}
+ */
+ @Deprecated
+ public void warn(String msg, Throwable t);
+
+ /**
+ * Log an exception (throwable) at the WARN level with an
+ * accompanying message.
+ *
+ * @param source - the object which send this log
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 1.2
+ */
+ public void warn(Object source, String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the ERROR level?
+ *
+ * @return <code>true</code> if this Logger is enabled for the ERROR level,
+ * <code>false</code> otherwise.
+ */
+ public boolean isErrorEnabled();
+
+ /**
+ * Log a message at the ERROR level.
+ *
+ * @param msg the message string to be logged
+ * @deprecated see {@link #error(Object, String)}
+ */
+ @Deprecated
+ public void error(String msg);
+
+ /**
+ * Log a message at the ERROR level.
+ *
+ * @param source - the object which send this log
+ * @param msg the message string to be logged
+ * @since 1.2
+ */
+ public void error(Object source, String msg);
+
+ /**
+ * Log an exception (throwable) at the ERROR level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @deprecated see {@link #error(Object, String, Throwable)}
+ */
+ @Deprecated
+ public void error(String msg, Throwable t);
+
+ /**
+ * Log an exception (throwable) at the ERROR level with an
+ * accompanying message.
+ *
+ * @param source - the object which send this log
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 1.2
+ */
+ public void error(Object source, String msg, Throwable t);
+
+ /** Set the minimum log level.
+ *
+ * @param level
+ */
+ public void setLogLevel(LogLevel level);
+
+ /** Replies the minimum log level.
+ *
+ * @return the minimal log level
+ */
+ public LogLevel getLogLevel();
+
+ /** Add listener on logger events.
+ *
+ * @param listener
+ */
+ public void addLoggerEventListener(LoggerEventListener listener);
+
+ /** Remove listener on logger events.
+ *
+ * @param listener
+ */
+ public void removeLoggerEventListener(LoggerEventListener listener);
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEvent.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEvent.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEvent.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,103 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.util.EventObject;
+
+/**
+ * This class provides a description of a logging event.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public class LoggerEvent extends EventObject {
+
+ private static final long serialVersionUID = -272287628530037390L;
+
+ private final Logger logger;
+ private final LogLevel level;
+ private final String message;
+ private final Throwable exception;
+
+ /**
+ * @param source is the source of the event.
+ * @param logger is the logger which has received the message.
+ * @param level is the level of the message.
+ * @param message is the text of the message.
+ */
+ public LoggerEvent(Object source, Logger logger, LogLevel level, String message) {
+ super(source);
+ this.logger = logger;
+ this.level = level;
+ this.message = message;
+ this.exception = null;
+ }
+
+ /**
+ * @param source is the source of the event.
+ * @param logger is the logger which has received the message.
+ * @param level is the level of the message
+ * @param message is the text of the message.
+ * @param exception is the exception associated to the message.
+ */
+ public LoggerEvent(Object source, Logger logger, LogLevel level, String message, Throwable exception) {
+ super(source);
+ this.logger = logger;
+ this.level = level;
+ this.message = message;
+ this.exception = exception;
+ }
+
+ /** Replies the logger which has received the event.
+ *
+ * @return the logger which as receivd the log.
+ * @since 1.2
+ */
+ public Logger getLogger() {
+ return this.logger;
+ }
+
+ /** Replies the log level of the event.
+ *
+ * @return the log level of the event.
+ */
+ public LogLevel getLogLevel() {
+ return this.level;
+ }
+
+ /** Replies the message in the event.
+ *
+ * @return the message in the event.
+ */
+ public String getMessage() {
+ return this.message;
+ }
+
+ /** Replies the exception associated to this event.
+ *
+ * @return the associated exception or <code>null</code>
+ */
+ public Throwable getException() {
+ return this.exception;
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEventListener.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEventListener.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggerEventListener.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2008 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.util.EventListener;
+
+/**
+ * Listener on logger events.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public interface LoggerEventListener extends EventListener {
+
+ /** Invoked when an event was logged in.
+ *
+ * @param event
+ */
+ public void onLoggedEvent(LoggerEvent event);
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggingSystem.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggingSystem.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/LoggingSystem.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,272 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2008 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/** This interface describes the body of an situated agent.
+ * The body is the only available interaction mean between
+ * an agent and the environment.
+ *
+ * @author Nicolas GAUD <gaud@xxxxxxxxxxx>
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class LoggingSystem {
+
+ private static final String[] PREFERED_LOGGERS = new String[] {
+ "org.arakhne.logging.ApacheLogger", //$NON-NLS-1$
+ "org.arakhne.logging.SunLogger", //$NON-NLS-1$
+ "org.arakhne.logging.ConsoleLogger" //$NON-NLS-1$
+ };
+
+ private static final LoggingSystem singleton = new LoggingSystem();
+
+ /**
+ * Return an anonymous logger.
+ *
+ * @return logger
+ */
+ public static Logger getLogger() {
+ return singleton.getAnonymousLogger();
+ }
+
+ /**
+ * Return a logger named according to the name parameter.
+ *
+ * @param name - The name of the logger.
+ * @return logger
+ */
+ public static Logger getLogger(String name) {
+ return singleton.getPreferedLogger(name);
+ }
+
+ /**
+ * Return a logger named corresponding to the class passed as parameter.
+ *
+ * @param clazz - the returned logger will be named after clazz
+ * @return logger
+ */
+ public static Logger getLogger(Class<?> clazz) {
+ return singleton.getPreferedLogger(clazz.getCanonicalName());
+ }
+
+ /**
+ * Returns the instance of <code>LoggingSystem</code> in use
+ * @return the instance of <code>LoggingSystem</code> in use
+ */
+ public static LoggingSystem getLoggingSystem() {
+ return singleton;
+ }
+
+ private final Map<String,Logger> preferedLoggers = new TreeMap<String,Logger>();
+ private Logger anonymousLogger = null;
+
+ private Class<? extends Logger> preferedLoggerType = null;
+
+ private LogLevel defaultLevel = LogLevel.WARNING;
+
+ private List<LoggerEventListener> listeners = null;
+
+ /**
+ */
+ protected LoggingSystem() {
+ //
+ }
+
+ /** Set the default log level for new loggers.
+ *
+ * @param logLevel
+ */
+ public void setDefaultLogLevel(LogLevel logLevel) {
+ assert(logLevel!=null);
+ this.defaultLevel = logLevel;
+ }
+
+ /** Replies the default log level for new loggers.
+ *
+ * @return the default log level, never <code>null</code>
+ */
+ public LogLevel getDefaultLogLevel() {
+ return this.defaultLevel;
+ }
+
+ /** Set the prefered type for the loggers.
+ *
+ * @param type is the prefered type or <code>null</code> to use the system default.
+ */
+ public void setPreferedLoggerType(Class<? extends Logger> type) {
+ this.preferedLoggerType = type;
+ }
+
+ /** Replies the prefered type for the loggers.
+ *
+ * @return the type of <code>null</code> to use the system default.
+ */
+ public Class<? extends Logger> getPreferedLoggerType() {
+ return this.preferedLoggerType;
+ }
+ /** Set the prefered logger.
+ *
+ * @param scopeName is the name of the scope for the new prefered logger.
+ * @param logger msut be a reference to the new prefered logger
+ * or <code>null</code> to use the default logger.
+ */
+ public void setPreferedLogger(String scopeName, Logger logger) {
+ if (logger==null)
+ this.preferedLoggers.remove(scopeName);
+ else
+ this.preferedLoggers.put(scopeName, logger);
+ }
+
+ /** Replies the prefered logger for the specified scope.
+ *
+ * @param scopeName is the name of the logger scope.
+ * @return the logger.
+ */
+ public Logger getPreferedLogger(String scopeName) {
+ Logger refLogger = this.preferedLoggers.get(scopeName);
+ if (refLogger!=null) return refLogger;
+ // Create default logger
+ Logger logger = createLoggerInstance(scopeName, this.defaultLevel);
+ this.preferedLoggers.put(scopeName, logger);
+ return logger;
+ }
+
+ /** Replies the logger to use when the scope is unknown.
+ *
+ * @return the anonymous logger.
+ */
+ public Logger getAnonymousLogger() {
+ Logger anonLogger = this.anonymousLogger;
+ if (anonLogger==null) {
+ anonLogger = createLoggerInstance(null, this.defaultLevel);
+ this.anonymousLogger = anonLogger;
+ }
+ return anonLogger;
+ }
+
+ /**
+ * @param name is the scope of the logger to create.
+ * @param minLogLevel is the minimal log level of the new logger.
+ * @return the created logged.
+ */
+ protected Logger createLoggerInstance(String name, LogLevel minLogLevel) {
+ Class<? extends Logger> type = findLoggerClass();
+ Logger logger = createLoggerInstance(type, name);
+ if (logger!=null) {
+ logger.setLogLevel(this.defaultLevel);
+ return logger;
+ }
+ type = findDefaultLoggerClass();
+ logger = createLoggerInstance(type, name);
+ if (logger!=null) {
+ logger.setLogLevel(this.defaultLevel);
+ return logger;
+ }
+ throw new Error("unable to create an instance of Logger"); //$NON-NLS-1$
+ }
+
+ private Logger createLoggerInstance(Class<? extends Logger> type, String name) {
+ if (type==null) return null;
+ if ((name!=null)&&(!"".equals(name))) { //$NON-NLS-1$
+ try {
+ Constructor<? extends Logger> cons = type.getConstructor(String.class);
+ return cons.newInstance(name);
+ }
+ catch(Exception _) {
+ //
+ }
+ }
+ try {
+ return type.newInstance();
+ }
+ catch(Exception _) {
+ //
+ }
+ return null;
+ }
+
+ /**
+ * @return the type of the the preferred logging system.
+ */
+ protected final Class<? extends Logger> findLoggerClass() {
+ if (this.preferedLoggerType!=null) return this.preferedLoggerType;
+ return findDefaultLoggerClass();
+ }
+
+ /**
+ * @return the type of the the preferred logging system.
+ */
+ @SuppressWarnings("unchecked")
+ protected Class<? extends Logger> findDefaultLoggerClass() {
+ for(String className : PREFERED_LOGGERS) {
+ try {
+ Class<?> type = Class.forName(className);
+ if (type!=null && Logger.class.isAssignableFrom(type)) return (Class<? extends Logger>)type;
+ }
+ catch(Exception _) {
+ //
+ }
+ }
+ return null;
+ }
+
+ /** Add listener on logger events.
+ *
+ * @param listener
+ */
+ public final void addLoggerEventListener(LoggerEventListener listener) {
+ if (this.listeners==null) {
+ this.listeners = new ArrayList<LoggerEventListener>();
+ }
+ this.listeners.add(listener);
+ }
+
+ /** Remove listener on logger events.
+ *
+ * @param listener
+ */
+ public void removeLoggerEventListener(LoggerEventListener listener) {
+ if (this.listeners!=null) {
+ this.listeners.remove(listener);
+ if (this.listeners.isEmpty())
+ this.listeners = null;
+ }
+ }
+
+ /** Notify the logger event listeners.
+ *
+ * @param event
+ */
+ final void fireLoggerEvent(LoggerEvent event) {
+ if (this.listeners!=null) {
+ for(LoggerEventListener listener : this.listeners) {
+ listener.onLoggedEvent(event);
+ }
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/SunLogger.java
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/SunLogger.java (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/java/org/arakhne/logging/SunLogger.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND and Nicolas GAUD
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.logging;
+
+import java.util.logging.Level;
+
+/**
+ * This class provides the concrete implementation of the <code>Logger</code>
+ * interface. This impl is based on the Sun's Logging Facade for Java
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see Logger
+ */
+public class SunLogger extends AbstractLogger {
+
+ private final java.util.logging.Logger bindedLogger;
+
+ /**
+ * Create an unamed logger based of Sun's logging system.
+ */
+ public SunLogger() {
+ this.bindedLogger = java.util.logging.Logger.getAnonymousLogger();
+ this.bindedLogger.setLevel(Level.ALL);
+ }
+
+ /**
+ * Create a named logger based of Sun's logging system.
+ *
+ * @param name is the name of the logger.
+ */
+ public SunLogger(String name) {
+ this.bindedLogger = java.util.logging.Logger.getLogger(name);
+ this.bindedLogger.setLevel(toSunLevel(getLogLevel()));
+ }
+
+// **************************************************************************************//
+
+ /** Translate a logging level into the same thing for Sun's logging system.
+ *
+ * @param level is the level to translate
+ * @return the Sun's level
+ */
+ protected Level toSunLevel(LogLevel level) {
+ switch(level) {
+ case NONE:
+ return Level.OFF;
+ case ERROR:
+ return Level.SEVERE;
+ case WARNING:
+ return Level.WARNING;
+ case INFO:
+ return Level.INFO;
+ case DEBUG:
+ return Level.CONFIG;
+ }
+ return Level.OFF;
+ }
+
+ /** {@InheritDoc}
+ */
+ @Override
+ public void log(Object source, LogLevel level, String msg) {
+ this.bindedLogger.log(toSunLevel(level),msg);
+ fireLoggerEvent(source, level, msg);
+ }
+
+ /** {@InheritDoc}
+ */
+ public void log(Object source, LogLevel level, String msg, Throwable exception) {
+ this.bindedLogger.log(toSunLevel(level),msg,exception);
+ fireLoggerEvent(source, level, msg);
+ }
+
+
+// **************************************************************************************//
+
+ /** {@InheritDoc}
+ *
+ * @return {@InheritDoc}
+ */
+ public String getName() {
+ return this.bindedLogger.getName();
+ }
+
+ /** Set the minimum log level.
+ *
+ * @param level
+ */
+ @Override
+ public void setLogLevel(LogLevel level) {
+ super.setLogLevel(level);
+ this.bindedLogger.setLevel(toSunLevel(level));
+ }
+
+}
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERROR = Error
+WARNING = Warning
+INFO = Information
+DEBUG = Debug
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_de.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_de.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_de.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERROR = St\xF6rung
+WARNING = Warnen
+INFO = Informationen
+DEBUG = Auspr\xFCfen mitteilung en
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_es.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_es.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_es.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERROR = Error
+WARNING = Cuidado
+INFO = Informaci\xF3n
+DEBUG = Eliminan errores del mensaje
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_fr.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_fr.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_fr.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERROR = Erreur
+WARNING = Avertissement
+INFO = Information
+DEBUG = D\xE9veloppement
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_it.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_it.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_it.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERROR = Errore
+WARNING = Avvertire
+INFO = Informazioni
+DEBUG = Mettono a punto il messaggio
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_nl.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_nl.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_nl.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,23 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERROR = Fout
+WARNING = Waarschuwing
+INFO = Informatie
+DEBUG = Zuivert bericht
Added: tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_pt.properties
===================================================================
--- tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_pt.properties (rev 0)
+++ tags/afc-2.0/arakhneLogger/src/main/resources/org/arakhne/logging/AbstractStandAloneLogger_pt.properties 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,25 @@
+# $Id$
+#
+# Copyright (C) 2009 Stéphane GALLAND and Nicolas GAUD
+#
+# 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
+# This program is free software; you can redistribute it and/or modify
+
+ERRO = ADVERT\xCANCIA = A informa\xE7\xE3o = a ELIMINAM ERROS =
+
+ERROR = Erro
+WARNING = Advert\xEAncia
+INFO = Informa\xE7\xE3o
+DEBUG = Eliminam erros
Added: tags/afc-2.0/arakhneRefs/pom.xml
===================================================================
--- tags/afc-2.0/arakhneRefs/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneRefs/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>afc</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>2.0</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneRefs</artifactId>
+ <packaging>jar</packaging>
+ <version>5.2</version>
+ <name>${pom.artifactId}</name>
+ <url>http://www.arakhne.org/arakhneRefs/</url>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,534 @@
+/*
+ * $Id: WeakValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak/soft values</em>. An entry in a
+ * <tt>AbstractWeakSoftValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+public abstract class AbstractWeakSoftValueMap<K,V> extends AbstractMap<K,V> {
+
+ /** Defines the NULL object inside a WeakValueMap.
+ *
+ * @see #maskNull(Object)
+ */
+ protected static final Object NULL_VALUE = new Object();
+
+ /** Mask the null values given by the used of this map.
+ * <p>
+ * This method replaces the <code>null</code> value by
+ * the internal representation {@link #NULL_VALUE}.
+ *
+ * @param <V> is the type of the value.
+ * @param value is the value given by the user of this map.
+ * @return the internal representation of the value.
+ * @see #unmaskNull(Object)
+ */
+ @SuppressWarnings("unchecked")
+ protected static <V> V maskNull(V value) {
+ return (value==null) ? (V)NULL_VALUE : value;
+ }
+
+ /** Unmask the null values given by the used of this map.
+ * <p>
+ * This method replaces the internal representation
+ * {@link #NULL_VALUE} of null values by its user representation
+ * <code>null</code>.
+ *
+ * @param <V> is the type of the value.
+ * @param value is the value given by the user of this map.
+ * @return the internal representation of the value.
+ * @see #maskNull(Object)
+ */
+ protected static <V> V unmaskNull(V value) {
+ return (value==NULL_VALUE) ? null : value;
+ }
+
+ private boolean autoExpurge = false;
+ private final HashMap<K,WeakSoftValue<K,V>> map;
+ private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity the initial capacity
+ * @param loadFactor the load factor
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public AbstractWeakSoftValueMap(int initialCapacity, float loadFactor) {
+ this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity, loadFactor);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity the initial capacity.
+ * @throws IllegalArgumentException if the initial capacity is negative.
+ */
+ public AbstractWeakSoftValueMap(int initialCapacity) {
+ this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public AbstractWeakSoftValueMap() {
+ this.map = new HashMap<K,WeakSoftValue<K,V>>();
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public AbstractWeakSoftValueMap(Map<? extends K, ? extends V> m) {
+ this.map = new HashMap<K,WeakSoftValue<K,V>>();
+ putAll(m);
+ }
+
+ /** Clean the references that was marked as released inside
+ * the queue.
+ */
+ protected final void expurgeNow() {
+ if (this.autoExpurge)
+ expurge();
+ else
+ expurgeQueuedReferences();
+ }
+
+ /** Replies if this map expurge all the released references
+ * even if they are not enqueued by the virtual machine
+ *
+ * @return <code>true</code> is the values are deeply expurged when they
+ * are released from the moemory, otherwise <code>false</code>
+ */
+ public final boolean isDeeplyExpurge() {
+ return this.autoExpurge;
+ }
+
+ /** Set if this map expurge all the released references
+ * even if they are not enqueued by the virtual machine
+ *
+ * @param deeplyExpurge must be <code>true</code> to
+ * expurge all the released values, otherwise <code>false</code>
+ * to expurge only the enqueued values.
+ * @return the old value of this flag
+ */
+ public final boolean setDeeplyExpurge(boolean deeplyExpurge) {
+ boolean old = this.autoExpurge;
+ this.autoExpurge = deeplyExpurge;
+ return old;
+ }
+
+ /** Clean the references that was marked as released inside
+ * the queue.
+ */
+ public final void expurgeQueuedReferences() {
+ Reference<? extends V> o;
+ while((o = this.queue.poll()) != null) {
+ if (o instanceof WeakSoftValue<?,?>) {
+ this.map.remove(((WeakSoftValue<?,?>)o).getKey());
+ }
+ o.clear();
+ }
+ }
+
+ /** Clean the references that was released.
+ */
+ public final void expurge() {
+ Reference<? extends V> o;
+
+ Iterator<Entry<K,WeakSoftValue<K,V>>> iter = this.map.entrySet().iterator();
+ Entry<K,WeakSoftValue<K,V>> entry;
+ WeakSoftValue<K,V> value;
+ while (iter.hasNext()) {
+ entry = iter.next();
+ if (entry!=null) {
+ value = entry.getValue();
+ if ((value!=null)&&
+ ((value.isEnqueued())||(value.get()==null))) {
+ value.enqueue();
+ value.clear();
+ }
+ }
+ }
+ entry = null;
+ value = null;
+
+ while((o = this.queue.poll()) != null) {
+ if (o instanceof WeakSoftValue<?,?>) {
+ this.map.remove(((WeakSoftValue<?,?>)o).getKey());
+ }
+ o.clear();
+ }
+ }
+
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @param refQueue is the reference queue to use
+ * @return the new storage object
+ */
+ protected abstract WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> refQueue);
+
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @return the new storage object
+ */
+ protected final WeakSoftValue<K,V> makeValue(K k, V v) {
+ return makeValue(k, v, this.queue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final V put(K key, V value) {
+ expurgeNow();
+ WeakSoftValue<K,V> ret = this.map.put(key, makeValue(key, value, this.queue));
+ if(ret == null) return null;
+ return ret.getValue();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final Set<Entry<K,V>> entrySet() {
+ expurgeNow();
+ return new InnerEntrySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final boolean equals(Object o) {
+ expurgeNow();
+ return super.equals(o);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int hashCode() {
+ expurgeNow();
+ return hashCode();
+ }
+
+ /**
+ * This interface provides information about the pairs inside
+ * a map with weak/soft reference values.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ protected interface WeakSoftValue<K,V> extends Entry<K,V> {
+
+ /**
+ * @return if the value is enqueued into a reference queue.
+ */
+ public boolean isEnqueued();
+
+ /**
+ * @return the weak/soft reference.
+ */
+ public V get();
+
+ /**
+ * @return if the value was enqueued
+ */
+ public boolean enqueue();
+
+ /**
+ */
+ public void clear();
+
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ @SuppressWarnings("synthetic-access")
+ private class InnerEntrySet implements Set<Entry<K,V>> {
+
+ public InnerEntrySet() {
+ //
+ }
+
+ @Override
+ public final boolean add(java.util.Map.Entry<K, V> e) {
+ K key = e.getKey();
+ V value = e.getValue();
+ return AbstractWeakSoftValueMap.this.map.put(key,
+ makeValue(key, value)) == null;
+ }
+
+ @Override
+ public final boolean addAll(Collection<? extends java.util.Map.Entry<K, V>> c) {
+ boolean ok = true;
+ for(java.util.Map.Entry<K, V> entry : c) {
+ ok = add(entry) && ok;
+ }
+ return ok;
+ }
+
+ @Override
+ public final void clear() {
+ AbstractWeakSoftValueMap.this.map.clear();
+ }
+
+ @Override
+ public final boolean contains(Object o) {
+ if (o instanceof Entry<?,?>) {
+ try {
+ expurgeNow();
+ return AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean containsAll(Collection<?> c) {
+ boolean ok;
+ expurgeNow();
+ for(Object o : c) {
+ ok = false;
+ if (o instanceof Entry<?,?>) {
+ try {
+ ok = AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ if (!ok) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public final boolean isEmpty() {
+ expurgeNow();
+ return AbstractWeakSoftValueMap.this.map.isEmpty();
+ }
+
+ @Override
+ public final Iterator<java.util.Map.Entry<K, V>> iterator() {
+ return new InnerIterator();
+ }
+
+ @Override
+ public final boolean remove(Object o) {
+ if (o instanceof Entry<?,?>) {
+ try {
+ return AbstractWeakSoftValueMap.this.map.remove(((Entry<?,?>)o).getKey())!=null;
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean removeAll(Collection<?> c) {
+ boolean ok = true;
+ for(Object o : c) {
+ ok = remove(o) && ok;
+ }
+ return ok;
+ }
+
+ @Override
+ public final boolean retainAll(Collection<?> c) {
+ expurgeNow();
+ Collection<K> keys = AbstractWeakSoftValueMap.this.map.keySet();
+ Iterator<K> iterator = keys.iterator();
+ K key;
+ boolean changed = false;
+ while (iterator.hasNext()) {
+ key = iterator.next();
+ if (!c.contains(key)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ public final int size() {
+ expurgeNow();
+ return AbstractWeakSoftValueMap.this.map.size();
+ }
+
+ @Override
+ public final Object[] toArray() {
+ expurgeNow();
+ Object[] tab = new Object[AbstractWeakSoftValueMap.this.map.size()];
+ return toArray(tab);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final <T> T[] toArray(T[] a) {
+ Entry[] tab;
+ expurgeNow();
+ int count = AbstractWeakSoftValueMap.this.map.size();
+ if (a==null || a.length<count) {
+ tab = new Entry[count];
+ }
+ else {
+ tab = (Entry[])a;
+ }
+
+ Iterator<java.util.Map.Entry<K, V>> iterator = iterator();
+ int i = 0;
+ while (i<tab.length && iterator.hasNext()) {
+ tab[i] = iterator.next();
+ }
+
+ return (T[])tab;
+ }
+
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ private class InnerIterator implements Iterator<Entry<K,V>> {
+
+ private final Iterator<Entry<K,WeakSoftValue<K,V>>> originalIterator;
+ private Entry<K,V> next;
+
+ @SuppressWarnings("synthetic-access")
+ public InnerIterator() {
+ this.originalIterator = AbstractWeakSoftValueMap.this.map.entrySet().iterator();
+ this.next = searchNext();
+ }
+
+ private Entry<K,V> searchNext() {
+ Entry<K,WeakSoftValue<K,V>> originalNext;
+ WeakSoftValue<K,V> wValue;
+ Entry<K,V> cnext = null;
+ while (cnext==null && this.originalIterator.hasNext()) {
+ originalNext = this.originalIterator.next();
+ if (originalNext!=null) {
+ wValue = originalNext.getValue();
+ if (wValue!=null) {
+ cnext = new InnerEntry(wValue.getValue(), originalNext);
+ }
+ }
+ }
+ return cnext;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.next!=null;
+ }
+
+ @Override
+ public java.util.Map.Entry<K, V> next() {
+ Entry<K,V> cnext = this.next;
+ this.next = searchNext();
+ return cnext;
+ }
+
+ @Override
+ public void remove() {
+ this.originalIterator.remove();
+ }
+
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ private class InnerEntry implements Entry<K,V> {
+
+ private final Entry<K,WeakSoftValue<K,V>> original;
+ private V value;
+
+ public InnerEntry(V v, Entry<K,WeakSoftValue<K,V>> o) {
+ this.original = o;
+ this.value = v;
+ }
+
+ @Override
+ public K getKey() {
+ return this.original.getKey();
+ }
+
+ @Override
+ public V getValue() {
+ return this.value;
+ }
+
+ @Override
+ public V setValue(V value) {
+ this.value = value;
+ return this.original.getValue().setValue(value);
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableSoftReference.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableSoftReference.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableSoftReference.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,148 @@
+/*
+ * $Id: ComparableSoftReference.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+
+/**
+ * This class is a WeakReference that allows to be
+ * compared on its pointed value.
+ *
+ * @param <T> is the type of the referenced object.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+public class ComparableSoftReference<T> extends SoftReference<T> implements Comparable<Object> {
+
+ /**
+ * @param referent is the referenced object.
+ */
+ public ComparableSoftReference(T referent) {
+ super(referent);
+ }
+
+ /**
+ * @param referent is the referenced object.
+ * @param queue is the object that will be notified of the memory released for the referenced object.
+ */
+ public ComparableSoftReference(T referent, ReferenceQueue<? super T> queue) {
+ super(referent,queue);
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ return compareTo(o)==0;
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ T cur = get();
+ return cur==null ? 0 : cur.hashCode();
+ }
+
+ /** Compare this reference to the specified object
+ * based on the {@link Object#hashCode()} if the
+ * references are not equals.
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public int compareTo(Object o) {
+ Object oth = (o instanceof Reference) ? ((Reference<?>)o).get() : o;
+ T cur = get();
+
+ if (oth==null && cur==null) return 0;
+ if (cur==null) return 1;
+ if (oth==null) return -1;
+
+ if (cur instanceof Comparable) {
+ try {
+ return ((Comparable<Object>)cur).compareTo(oth);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+
+ if (oth instanceof Comparable) {
+ try {
+ return -((Comparable<Object>)oth).compareTo(cur);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+
+ return oth.hashCode() - cur.hashCode();
+ }
+
+ /** Compare this reference to the specified object
+ * based on the {@link Object#hashCode()} if the
+ * references are not equals.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @deprecated call {@link #compareTo(Object)} insteed
+ */
+ @Deprecated
+ public int compareToObject(T o) {
+ return compareTo(o);
+ }
+
+ /** Compare this reference to the specified object
+ * based on the {@link Object#hashCode()} if the
+ * references are not equals.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @deprecated call {@link #compareTo(Object)} insteed
+ */
+ @Deprecated
+ public int compareToRef(Reference<T> o) {
+ return compareTo(o);
+ }
+
+ /** {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ T obj = get();
+ if (obj==null) buffer.append("#null#"); //$NON-NLS-1$
+ else buffer.append(obj.toString());
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableWeakReference.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableWeakReference.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ComparableWeakReference.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,148 @@
+/*
+ * $Id: ComparableWeakReference.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+/**
+ * This class is a WeakReference that allows to be
+ * compared on its pointed value.
+ *
+ * @param <T> is the type of the referenced object.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+public class ComparableWeakReference<T> extends WeakReference<T> implements Comparable<Object> {
+
+ /**
+ * @param referent is the referenced object.
+ */
+ public ComparableWeakReference(T referent) {
+ super(referent);
+ }
+
+ /**
+ * @param referent is the referenced object.
+ * @param queue is the object that will be notified of the memory released for the referenced object.
+ */
+ public ComparableWeakReference(T referent, ReferenceQueue<? super T> queue) {
+ super(referent,queue);
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ return compareTo(o)==0;
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ T cur = get();
+ return cur==null ? 0 : cur.hashCode();
+ }
+
+ /** Compare this reference to the specified object
+ * based on the {@link Object#hashCode()} if the
+ * references are not equals.
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public int compareTo(Object o) {
+ Object oth = (o instanceof Reference) ? ((Reference<?>)o).get() : o;
+ T cur = get();
+
+ if (oth==null && cur==null) return 0;
+ if (cur==null) return 1;
+ if (oth==null) return -1;
+
+ if (cur instanceof Comparable) {
+ try {
+ return ((Comparable<Object>)cur).compareTo(oth);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+
+ if (oth instanceof Comparable) {
+ try {
+ return -((Comparable<Object>)oth).compareTo(cur);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+
+ return oth.hashCode() - cur.hashCode();
+ }
+
+ /** Compare this reference to the specified object
+ * based on the {@link Object#hashCode()} if the
+ * references are not equals.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @deprecated call {@link #compareTo(Object)} insteed
+ */
+ @Deprecated
+ public int compareToObject(T o) {
+ return compareTo(o);
+ }
+
+ /** Compare this reference to the specified object
+ * based on the {@link Object#hashCode()} if the
+ * references are not equals.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @deprecated call {@link #compareTo(Object)} insteed
+ */
+ @Deprecated
+ public int compareToRef(Reference<T> o) {
+ return compareTo(o);
+ }
+
+ /** {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ T obj = get();
+ if (obj==null) buffer.append("#null#"); //$NON-NLS-1$
+ else buffer.append(obj.toString());
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ReferenceListener.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ReferenceListener.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/ReferenceListener.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.EventListener;
+
+/**
+ * Listener on the release of a reference.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public interface ReferenceListener extends EventListener {
+
+ /** Invoked when at least one reference was released.
+ * <p>
+ * No reference is given to avoid strong referencing of the released objects
+ * inside the listener's source code.
+ *
+ * @param released is the count of released objects.
+ */
+ public void referenceReleased(int released);
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,226 @@
+/*
+ * $Id: SoftValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ *
+ * Copyright (C) 2005-2007 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>SoftValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from <code>WeakHashMap</code>
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+public class SoftValueMap<K,V> extends AbstractWeakSoftValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity the initial capacity
+ * @param loadFactor the load factor
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public SoftValueMap(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity the initial capacity.
+ * @throws IllegalArgumentException if the initial capacity is negative.
+ */
+ public SoftValueMap(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public SoftValueMap() {
+ super();
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public SoftValueMap(Map<? extends K, ? extends V> m) {
+ super(m);
+ }
+
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @param queue is the reference queue to use
+ * @return the new storage object
+ */
+ @Override
+ protected WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+ return new Value<K,V>(k, v, queue);
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ private static class Value<K,V> extends SoftReference<V> implements WeakSoftValue<K,V> {
+
+ private final K k;
+
+ /**
+ * @param k is the key.
+ * @param v is the value.
+ * @param queue is the memory-release listener.
+ */
+ Value(K k, V v, ReferenceQueue<V> queue) {
+ super(maskNull(v), queue);
+ this.k = k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ K key = getKey();
+ buffer.append(key==null ? null : key.toString());
+ buffer.append('=');
+ if (isEnqueued()) {
+ buffer.append("Q#"); //$NON-NLS-1$
+ }
+ else {
+ buffer.append("P#"); //$NON-NLS-1$
+ }
+ V v = getValue();
+ buffer.append((v==null ? null : v.toString()));
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ public K getKey() {
+ return this.k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ public V getValue() {
+ return unmaskNull(get());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ public V setValue(V o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ Object val = getValue();
+ return (getKey()==null ? 0 : getKey().hashCode()) ^
+ (val==null ? 0 : val.hashCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Entry) {
+ Entry<K,V> e = (Entry<K,V>)o;
+ Object e1val = getValue();
+ Object e2val = e.getValue();
+ return (getKey()==null ?
+ e.getKey()==null : getKey().equals(e.getKey())) &&
+ (e1val==null ? e2val==null : e1val.equals(e2val));
+ }
+ return false;
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,439 @@
+/*
+ * $Id: WeakArrayList.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A array-based <tt>List</tt> implementation with <em>weak keys</em>.
+ * An entry in a <tt>WeakArrayList</tt> will automatically be removed when
+ * it is no longer in ordinary use.
+ *
+ * <p> The behavior of the <tt>WeakArrayList</tt> class depends in part upon
+ * the actions of the garbage collector, so several familiar (though not
+ * required) <tt>List</tt> invariants do not hold for this class. Because
+ * the garbage collector may discard values at any time, a
+ * <tt>WeakArrayList</tt> may behave as though an unknown thread is silently
+ * removing entries. In particular, even if you synchronize on a
+ * <tt>WeakArrayList</tt> instance and invoke none of its mutator methods, it
+ * is possible for the <tt>size</tt> method to return smaller values over
+ * time, for the <tt>isEmpty</tt> method to return <tt>false</tt> and
+ * then <tt>true</tt>, for the <tt>contains</tt> method to return
+ * <tt>true</tt> and later <tt>false</tt> for a given value, for the
+ * <tt>get</tt> method to return a value for a given key but later return
+ * <tt>null</tt>, for the <tt>add</tt> method to return
+ * <tt>null</tt> and the <tt>remove</tt> method to return
+ * <tt>false</tt> for a value that previously appeared to be in the list.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <T> is the type of the array's elements.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+public class WeakArrayList<T> extends AbstractList<T> {
+
+ private static final long serialVersionUID = 2601162363164961860L;
+
+ /** This value represents a null value given by the user.
+ */
+ private static final Object NULL_VALUE = new Object();
+
+ /** Replies the null value given by the user by the corresponding null object.
+ */
+ @SuppressWarnings("unchecked")
+ private static <T> T maskNull(T value) {
+ return (value==null) ? (T)NULL_VALUE : value;
+ }
+
+ /** Replies the value given by the user.
+ */
+ private static <T> T unmaskNull(T value) {
+ return (value==NULL_VALUE) ? null : value;
+ }
+
+ private final transient ReferenceQueue<T> queue = new ReferenceQueue<T>();
+
+ private Object[] data;
+
+ private int size;
+
+ private boolean enquedElement = false;
+
+ private List<ReferenceListener> listeners = null;
+
+ /**
+ * Constructs an empty list with the specified initial capacity.
+ *
+ * @param initialCapacity the initial capacity of the list
+ * @exception IllegalArgumentException if the specified initial capacity
+ * is negative
+ */
+ public WeakArrayList(int initialCapacity) {
+ if (initialCapacity < 0)
+ throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); //$NON-NLS-1$
+ this.data = new Object[initialCapacity];
+ this.size = 0;
+ }
+
+ /**
+ * Constructs an empty list with an initial capacity of ten.
+ */
+ public WeakArrayList() {
+ this(10);
+ }
+
+ /**
+ * Constructs a list containing the elements of the specified
+ * collection, in the order they are returned by the collection's
+ * iterator.
+ *
+ * @param c the collection whose elements are to be placed into this list
+ * @throws NullPointerException if the specified collection is null
+ */
+ public WeakArrayList(Collection<? extends T> c) {
+ this.data = new Object[c.size()];
+ this.size = this.data.length;
+ int i=0;
+ for (T t : c) {
+ this.data[i] = createRef(t);
+ i++;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ Reference<T> ref;
+ T obj;
+ for(int i=0; i<this.size; i++) {
+ ref = (Reference<T>)this.data[i];
+ if (this.data[i]==null) obj = null;
+ else obj = ref.get();
+ buffer.append('{');
+ buffer.append(obj==null ? null : obj.toString());
+ buffer.append('}');
+ }
+ return buffer.toString();
+ }
+
+ /** Create and replies the reference for the specified object.
+ *
+ * @param obj is the object on which a weak reference must be attached.
+ * @return the weak reference.
+ */
+ private Reference<T> createRef(T obj) {
+ return new WeakReference<T>(maskNull(obj), this.queue);
+ }
+
+ /**
+ * Increases the capacity of this <tt>WeakArrayList</tt> instance, if
+ * necessary, to ensure that it can hold at least the number of elements
+ * specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ public void ensureCapacity(int minCapacity) {
+ this.modCount++;
+ int oldCapacity = this.data.length;
+ if (minCapacity > oldCapacity) {
+ Object[] oldData = this.data;
+ int newCapacity = (oldCapacity * 3)/2 + 1;
+ if (newCapacity < minCapacity)
+ newCapacity = minCapacity;
+ // minCapacity is usually close to size, so this is a win:
+ this.data = Arrays.copyOf(oldData, newCapacity);
+ }
+ }
+
+ /**
+ * Trims the capacity of this <tt>WeakArrayList</tt> instance to be the
+ * list's current size. An application can use this operation to minimize
+ * the storage of an <tt>WeakArrayList</tt> instance.
+ */
+ public void trimToSize() {
+ this.modCount++;
+ int oldCapacity = this.data.length;
+ if (this.size < oldCapacity) {
+ this.data = Arrays.copyOf(this.data, this.size);
+ }
+ }
+
+ /** Clean the references that was released.
+ * <p>
+ * Notifies the listeners if a reference was released.
+ *
+ * @return the size
+ */
+ @SuppressWarnings("unchecked")
+ public int expurge() {
+ // clear out ref queue.
+ while (this.queue.poll()!=null) {
+ this.enquedElement = true;
+ }
+
+ int j;
+
+ if (this.enquedElement) {
+ // Clear the table
+ Reference<? extends T> ref;
+ j=0;
+ for(int i=0; i<this.size; i++) {
+ ref = (Reference<T>)this.data[i];
+ if ((ref==null)||(ref.isEnqueued())||(ref.get()==null)) {
+ if (ref!=null) ref.clear();
+ this.data[i] = null;
+ }
+ else {
+ if (i!=j) {
+ this.data[j] = this.data[i];
+ this.data[i] = null;
+ }
+ j++;
+ }
+ }
+ this.enquedElement = false;
+ }
+ else {
+ j = this.size;
+ }
+
+ // Allocation of array may have caused GC, which may have caused
+ // additional entries to go stale. Removing these entries from the
+ // reference queue will make them eligible for reclamation.
+ while (this.queue.poll()!=null) {
+ this.enquedElement = true;
+ }
+
+ int oldSize = this.size;
+ this.size = j;
+
+ if (j<oldSize) {
+ fireReferenceRelease(oldSize - j);
+ }
+
+ return this.size;
+ }
+
+ /** Verify if the specified index is inside the array.
+ *
+ * @param index is the index totest
+ * @param allowLast indicates if the last elements is assumed to be valid or not.
+ */
+ protected void assertRange(int index, boolean allowLast) {
+ int csize = expurge();
+ if (index<0)
+ throw new IndexOutOfBoundsException("invalid negative value: "+Integer.toString(index)); //$NON-NLS-1$
+ if ((allowLast)&&(index>csize))
+ throw new IndexOutOfBoundsException("index>"+csize+": "+Integer.toString(index)); //$NON-NLS-1$ //$NON-NLS-2$
+ if ((!allowLast)&&(index>=csize))
+ throw new IndexOutOfBoundsException("index>="+csize+": "+Integer.toString(index)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ public int size() {
+ return expurge();
+ }
+
+ /** {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public T get(int index) {
+ T value;
+ do {
+ assertRange(index,false);
+ value = ((Reference<T>)this.data[index]).get();
+ }
+ while (value==null);
+ return unmaskNull(value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public T set(int index, T element) {
+ T oldValue;
+ Reference<T> ref;
+ do {
+ assertRange(index, false);
+ ref = (Reference<T>)this.data[index];
+ oldValue = ref.get();
+ }
+ while (oldValue==null);
+ ref.clear();
+ this.data[index] = createRef(element);
+ this.modCount++;
+ return unmaskNull(oldValue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void add(int index, T element) {
+ assertRange(index,true);
+ ensureCapacity(this.size+1);
+ System.arraycopy(this.data, index, this.data, index+1, this.size-index);
+ this.data[index] = createRef(element);
+ this.size++;
+ this.modCount++;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public T remove(int index) {
+ T oldValue;
+ Reference<T> ref;
+ do {
+ assertRange(index, false);
+ ref = (Reference<T>)this.data[index];
+ oldValue = ref.get();
+ }
+ while (oldValue==null);
+ ref.clear();
+ System.arraycopy(this.data, index+1, this.data, index, this.size-index-1);
+ this.data[this.size-1] = null;
+ this.size--;
+ this.modCount++;
+ return unmaskNull(oldValue);
+ }
+
+ /** Add listener on reference's release.
+ *
+ * @param listener
+ */
+ public void addReferenceListener(ReferenceListener listener) {
+ if (this.listeners==null) {
+ this.listeners = new LinkedList<ReferenceListener>();
+ }
+ List<ReferenceListener> list = this.listeners;
+ synchronized(list) {
+ list.add(listener);
+ }
+ }
+
+ /** Remove listener on reference's release.
+ *
+ * @param listener
+ */
+ public void removeReferenceListener(ReferenceListener listener) {
+ List<ReferenceListener> list = this.listeners;
+ if (list!=null) {
+ synchronized(list) {
+ list.remove(listener);
+ if (list.isEmpty()) this.listeners = null;
+ }
+ }
+ }
+
+ /**
+ * Fire the reference release event.
+ *
+ * @param released is the count of released objects.
+ */
+ protected void fireReferenceRelease(int released) {
+ List<ReferenceListener> list = this.listeners;
+ if (list!=null && !list.isEmpty()) {
+ for(ReferenceListener listener : list) {
+ listener.referenceReleased(released);
+ }
+ }
+ }
+
+ /** Replies if this map expurge all the released references
+ * even if they are not enqueued by the virtual machine
+ *
+ * @return <code>true</code>
+ * @deprecated Always returns <code>true</code>, do not use!
+ */
+ @Deprecated
+ public boolean isDeeplyExpurge() {
+ return true;
+ }
+
+ /** Set if this map expurge all the released references
+ * even if they are not enqueued by the virtual machine
+ *
+ * @param deeplyExpurge must be <code>true</code> to
+ * expurge all the released values, otherwise <code>false</code>
+ * to expurge only the enqueued values.
+ * @return the old value of this flag
+ * @deprecated Do nothing, do not use!
+ */
+ @Deprecated
+ public boolean setDeeplyExpurge(boolean deeplyExpurge) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** Clean the references that was marked as released inside
+ * the queue.
+ *
+ * @return the size
+ * @deprecated Do nothing, do not use!
+ */
+ @Deprecated
+ public int expurgeQueuedReferences() {
+ throw new UnsupportedOperationException();
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,227 @@
+/*
+ * $Id: WeakValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ *
+ * Copyright (C) 2005-2007 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>WeakValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap}
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+public class WeakValueMap<K,V> extends AbstractWeakSoftValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity the initial capacity
+ * @param loadFactor the load factor
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public WeakValueMap(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity the initial capacity.
+ * @throws IllegalArgumentException if the initial capacity is negative.
+ */
+ public WeakValueMap(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public WeakValueMap() {
+ super();
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public WeakValueMap(Map<? extends K, ? extends V> m) {
+ super(m);
+ }
+
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @param queue is the reference queue to use
+ * @return the new storage object
+ */
+ @Override
+ protected WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+ return new Value<K,V>(k, v, queue);
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ private static class Value<K,V> extends WeakReference<V> implements WeakSoftValue<K,V> {
+
+ private final K k;
+
+ /**
+ * @param k is the key.
+ * @param v is the value.
+ * @param queue is the memory-release listener.
+ */
+ Value(K k, V v, ReferenceQueue<V> queue) {
+ super(maskNull(v), queue);
+ this.k = k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ K key = getKey();
+ buffer.append(key==null ? null : key.toString());
+ buffer.append('=');
+ if (isEnqueued()) {
+ buffer.append("Q#"); //$NON-NLS-1$
+ }
+ else {
+ buffer.append("P#"); //$NON-NLS-1$
+ }
+ V v = getValue();
+ buffer.append((v==null ? null : v.toString()));
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ public K getKey() {
+ return this.k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ public V getValue() {
+ return unmaskNull(get());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ public V setValue(V o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ Object val = getValue();
+ return (getKey()==null ? 0 : getKey().hashCode()) ^
+ (val==null ? 0 : val.hashCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Entry) {
+ Entry<K,V> e = (Entry<K,V>)o;
+ Object e1val = getValue();
+ Object e2val = e.getValue();
+ return (getKey()==null ?
+ e.getKey()==null : getKey().equals(e.getKey())) &&
+ (e1val==null ? e2val==null : e1val.equals(e2val));
+ }
+ return false;
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/main/resources/AUTHORS
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/resources/AUTHORS (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/resources/AUTHORS 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,2 @@
+Stephane GALLAND <galland@xxxxxxxxxxx>
+Nicolas GAUD <gaud@xxxxxxxxxxx>
Added: tags/afc-2.0/arakhneRefs/src/main/resources/COPYING
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/resources/COPYING (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/resources/COPYING 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
Added: tags/afc-2.0/arakhneRefs/src/main/resources/Changelog
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/resources/Changelog (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/resources/Changelog 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,49 @@
+arakhneRefs-5.1
+
+ * Bug fix: the Comparable weak/soft references throw ClassCastException when the
+ object passed to compareTo() is not castable to the generic T.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2009-02-20
+
+
+arakhneRefs-5.0
+
+ * Reimplement the AbstractWeakSoftValueMap to avoid execeptions.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2009-02-03
+
+
+arakhneRefs-4.1
+
+ * Bug fix: avoid IllegalStateException from internal HashMap.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2009-02-03
+
+
+arakhneRefs-4.0
+
+ * Bug fix: avoid ConcurrentModificationException on SoftValueMap and WeakValueMap.
+ * Put the common code from SoftValueMap and WeakValueMap into a shared abstract class.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2009-02-02
+
+
+arakhneRefs-3.0
+
+ * Add the class SoftValueMap.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2008-02-18
+
+
+arakhneRefs-2.0
+
+ * Bug fixes inside the weak data structures.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2007-12-31
+
+
+arakhneLogger-1.0
+
+ * First public release.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2007-01-01
Added: tags/afc-2.0/arakhneRefs/src/main/resources/VERSION
===================================================================
--- tags/afc-2.0/arakhneRefs/src/main/resources/VERSION (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/main/resources/VERSION 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1 @@
+arakhneRefs 5.1
Added: tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractRepeatedTest.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractRepeatedTest.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractRepeatedTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,158 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.junit;
+
+import java.lang.ref.WeakReference;
+import java.util.Enumeration;
+
+import junit.extensions.TestDecorator;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+/** Test case that repeat another test.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public abstract class AbstractRepeatedTest extends TestDecorator {
+
+ private final int fTimesRepeat;
+
+ /**
+ * @param clazz
+ * @param repeat
+ */
+ public AbstractRepeatedTest(Class<? extends RepeatableTest> clazz, int repeat) {
+ this(new RepeatableTestSuite(clazz),repeat);
+ }
+
+ /**
+ * @param test
+ * @param repeat
+ */
+ public AbstractRepeatedTest(Test test, int repeat) {
+ super(test);
+ if (repeat < 0)
+ throw new IllegalArgumentException("Repetition count must be > 0"); //$NON-NLS-1$
+ this.fTimesRepeat= repeat;
+ }
+
+ @Override
+ public int countTestCases() {
+ return super.countTestCases()*this.fTimesRepeat;
+ }
+
+ @Override
+ public void run(TestResult result) {
+
+ final TestResultHandler handler = new TestResultHandler(result);
+ result.addListener(handler);
+
+ try {
+ for (int i= 0; i < this.fTimesRepeat; i++) {
+ if (result.shouldStop())
+ break;
+ ((RepeatableTest)this.fTest).setLoopIndex(i);
+ try {
+ super.run(result);
+ }
+ finally {
+ ((RepeatableTest)this.fTest).setLoopIndex(-1);
+ }
+ }
+ }
+ finally {
+ result.removeListener(handler);
+ }
+ }
+
+ @Override
+ public String toString() {
+ int idx = ((RepeatableTest)this.fTest).getLoopIndex();
+ if (idx>0)
+ return super.toString()+"(repeated "+idx+"/"+this.fTimesRepeat+")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return super.toString()+"(repeated)"; //$NON-NLS-1$
+ }
+
+ /** Handler on test result errors for a repeated test.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+ private class TestResultHandler implements TestListener {
+
+ private WeakReference<TestResult> result;
+
+ public TestResultHandler(TestResult result) {
+ this.result = new WeakReference<TestResult>(result);
+ }
+
+ public void addError(Test test, Throwable t) {
+ TestResult r = this.result.get();
+ if (r!=null) r.stop();
+ }
+
+ public void addFailure(Test test, AssertionFailedError t) {
+ TestResult r = this.result.get();
+ if (r!=null) r.stop();
+ }
+
+ public void endTest(Test test) {
+ //
+ }
+
+ public void startTest(Test test) {
+ //
+ }
+
+ } /* class TestResultHandler */
+
+ /** Test suite that could be repeated.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+ private static class RepeatableTestSuite extends TestSuite implements RepeatableTest {
+
+ private int loopIndex = -1;
+
+ public RepeatableTestSuite(Class<? extends RepeatableTest> clazz) {
+ super(clazz);
+ }
+
+ public void setLoopIndex(int index) {
+ this.loopIndex = index;
+ Enumeration<?> e = tests();
+ while (e.hasMoreElements()) {
+ RepeatableTest t = (RepeatableTest)e.nextElement();
+ t.setLoopIndex(index);
+ }
+ }
+
+ public int getLoopIndex() {
+ return this.loopIndex;
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractTestCase.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractTestCase.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/AbstractTestCase.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,761 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.junit;
+
+import java.awt.geom.Point2D;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import org.arakhne.junit.RepeatableTest;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/** Test case with utility functions.
+*
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public abstract class AbstractTestCase extends TestCase implements RepeatableTest {
+
+ private static String arrayToString(Object o) {
+ if (o==null) return null;
+ if (o instanceof boolean[])
+ return Arrays.toString((boolean[])o);
+ if (o instanceof byte[])
+ return Arrays.toString((byte[])o);
+ if (o instanceof char[])
+ return Arrays.toString((char[])o);
+ if (o instanceof short[])
+ return Arrays.toString((short[])o);
+ if (o instanceof int[])
+ return Arrays.toString((int[])o);
+ if (o instanceof long[])
+ return Arrays.toString((long[])o);
+ if (o instanceof float[])
+ return Arrays.toString((float[])o);
+ if (o instanceof double[])
+ return Arrays.toString((double[])o);
+ if (o instanceof Object[])
+ return Arrays.toString((Object[])o);
+ return o.toString();
+ }
+
+ /** Replies if the given elements is in the array.
+ * <p>
+ * This function is based on {@link Object#equals(java.lang.Object)}.
+ */
+ private static <T> boolean arrayContainsAll(T[] elts, T[] array) {
+ boolean found;
+ for (T elt : elts) {
+ found = false;
+ for (T t : array) {
+ if ((t==elt)||
+ ((t!=null)&&(t.equals(elt)))) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return true;
+ }
+
+ private int loopIndex = -1;
+
+ public int getLoopIndex() {
+ return this.loopIndex;
+ }
+
+ public void setLoopIndex(int index) {
+ this.loopIndex = index;
+ }
+
+ /**
+ * Format a failure message for invalid value.
+ *
+ * @param message is the message to reply.
+ * @param expected is the expected object.
+ * @param actual is the actual value of the object.
+ * @return the message
+ */
+ protected String formatFailMessage(String message, Object expected, Object actual) {
+ StringBuffer formatted = new StringBuffer();
+ if (message!=null) {
+ formatted.append(message);
+ formatted.append(' ');
+ }
+ formatted.append("expected:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(expected));
+ formatted.append("> but was:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(actual));
+ formatted.append(">"); //$NON-NLS-1$
+ return formatted.toString();
+ }
+
+ /**
+ * Format a failure message for invalid value.
+ *
+ * @param message is the first part of the message (optional).
+ * @param msg is the second part of the message (mandatory).
+ * @param actual is the actual value of the object.
+ * @return the message
+ */
+ protected String formatFailMessage(String message, String msg, Object actual) {
+ StringBuffer formatted = new StringBuffer();
+ if (message!=null) {
+ formatted.append(message);
+ formatted.append(' ');
+ }
+ formatted.append(msg);
+ formatted.append(" but was:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(actual));
+ formatted.append(">"); //$NON-NLS-1$
+ return formatted.toString();
+ }
+
+ /**
+ * Format a failure message for not-expected values.
+ *
+ * @param message is the message to reply.
+ * @param notexpected is the not-expected object.
+ * @return the message
+ */
+ protected String formatFailNegMessage(String message, Object notexpected) {
+ StringBuffer formatted = new StringBuffer();
+ if (message!=null) {
+ formatted.append(message);
+ formatted.append(' ');
+ }
+ formatted.append("not expected:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(notexpected));
+ formatted.append("> but the same"); //$NON-NLS-1$
+ return formatted.toString();
+ }
+
+ /** Asserts that two objects are not equal. If they are
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param notexpected is the value which is not expected by the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertNotEquals(String message, Object notexpected, Object actual) {
+ if ((notexpected!=actual)&&
+ ((notexpected==null)
+ ||
+ (!notexpected.equals(actual)))) return;
+ fail(formatFailNegMessage(message, notexpected));
+ }
+
+ /** Asserts that two objects are not equal. If they are
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param notexpected is the value which is not expected by the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertNotEquals(Object notexpected, Object actual) {
+ assertNotEquals(null, notexpected, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertEquals(String message, Object[] expectedObjects, Object actual) {
+ if ((expectedObjects!=null)&&(expectedObjects.length>0)) {
+ for (Object object : expectedObjects) {
+ if ((object==null)&&(actual==null)) return;
+ if ((object!=null)&&(object.equals(actual))) return;
+ }
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertEquals(Object[] expectedObjects, Object actual) {
+ assertEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param <T> is the type of the array.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertEquals(String message, T[] expectedObjects, T[] actual) {
+ if (expectedObjects==actual) return;
+ if ((expectedObjects!=null)&&(actual!=null)&&
+ (expectedObjects.length==actual.length)) {
+ boolean ok = true;
+ for(int i=0; i<expectedObjects.length; i++) {
+ if ((expectedObjects[i]!=null)||(actual[i]!=null)) {
+ if ((expectedObjects[i]==null)||(!expectedObjects[i].equals(actual[i]))) {
+ ok = false;
+ break;
+ }
+ }
+ }
+ if (ok) return;
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the array.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertEquals(T[] expectedObjects, T[] actual) {
+ assertEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param <T> is the type of the array.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertNotEquals(String message, T[] expectedObjects, T[] actual) {
+ if (expectedObjects!=actual) {
+ if ((expectedObjects!=null)&&(actual!=null)) {
+ if (expectedObjects.length!=actual.length) return;
+ boolean ok = true;
+ for(int i=0; i<expectedObjects.length; i++) {
+ if ((expectedObjects[i]!=null)||(actual[i]!=null)) {
+ if ((expectedObjects[i]==null)||(!expectedObjects[i].equals(actual[i]))) {
+ ok = false;
+ break;
+ }
+ }
+ }
+ if (!ok) return;
+ }
+ else return;
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel object is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the array.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertNotEquals(T[] expectedObjects, T[] actual) {
+ assertNotEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ * This assertion function tests the types of its parameters to call the best
+ * {@code assertEquals} function.
+ *
+ * @param expected is the expected value during the unit test.
+ * @param actual is the actual value of the object during the unit test.
+ * @see #assertEquals(Object, Object)
+ * @see #assertEquals(Object[], Object)
+ * @see #assertEquals(Object[], Object[])
+ */
+ protected void assertEqualsGeneric(Object expected, Object actual) {
+ assertEqualsGeneric(null, expected, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ * This assertion function tests the types of its parameters to call the best
+ * {@code assertEquals} function.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param expected is the expected value during the unit test.
+ * @param actual is the actual value of the object during the unit test.
+ * @see #assertEquals(Object, Object)
+ * @see #assertEquals(Object[], Object)
+ * @see #assertEquals(Object[], Object[])
+ */
+ protected void assertEqualsGeneric(String message, Object expected, Object actual) {
+ if ((expected!=null)&&(actual!=null)&&(expected.getClass().isArray())) {
+ if (actual.getClass().isArray())
+ assertEquals(message, (Object[])expected, (Object[])actual);
+ else
+ assertEquals(message, (Object[])expected, actual);
+ }
+ else assertEquals(message, expected, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(T[] expectedObjects, T[] actual) {
+ assertSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(String message, T[] expectedObjects, T[] actual) {
+ if (expectedObjects==actual) return;
+ if ((arrayContainsAll(expectedObjects, actual))&&(arrayContainsAll(actual, expectedObjects)))
+ return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(Collection<T> expectedObjects, Collection<T> actual) {
+ assertSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(String message, Collection<T> expectedObjects, Collection<T> actual) {
+ if (expectedObjects==actual) return;
+ if (similars(expectedObjects,actual)) return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ private <T> boolean similars(Collection<T> c1, Collection<T> c2) {
+ ArrayList<T> a = new ArrayList<T>();
+ a.addAll(c2);
+ for(T elt : c1) {
+ if (!a.remove(elt)) {
+ return false;
+ }
+ }
+ return a.isEmpty();
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertEquals(List<T> expectedObjects, List<T> actual) {
+ assertEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertEquals(String message, List<T> expectedObjects, List<T> actual) {
+ if (expectedObjects==actual) return;
+ if (equals(expectedObjects,actual)) return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ private <T> boolean equals(List<T> c1, List<T> c2) {
+ if (c1.size()!=c2.size()) return false;
+ int count = c1.size();
+ T e1, e2;
+ for(int i=0; i<count; i++) {
+ e1 = c1.get(i);
+ e2 = c2.get(i);
+ if ((e1!=e2)&&(!e1.equals(e2))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Asserts that the actuel similar is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertNotEquals(List<T> expectedObjects, List<T> actual) {
+ assertNotEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertNotEquals(String message, List<T> expectedObjects, List<T> actual) {
+ if ((expectedObjects!=actual)&&(!equals(expectedObjects,actual))) return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actual object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param <X> is the element's type of the values if they are arrays.
+ * @param message is the error message to put inside the assertion.
+ * @param expected is the expected value during the unit test.
+ * @param actual are the actual value of the object during the unit test.
+ */
+ @SuppressWarnings("unchecked")
+ protected <T, X> void assertSimilars(String message, T expected, T actual) {
+ if (expected==actual) return;
+ if (expected instanceof Collection)
+ assertSimilars(message, (Collection)expected, (Collection)actual);
+ else if (expected instanceof Point2D)
+ assertSimilars(message, (Point2D)expected, (Point2D)actual);
+ else if (expected instanceof Date)
+ assertSimilars(message, (Date)expected, (Date)actual);
+ else if (expected.getClass().isArray())
+ assertSimilars(message, (X[])expected, (X[])actual);
+ else
+ assertEquals(message, expected, actual);
+ }
+
+ /** Asserts that the actual object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values.
+ * @param <X> is the element's type of the values if they are arrays.
+ * @param message is the error message to put inside the assertion.
+ * @param expected is the expected value.
+ * @param actual is the current value.
+ */
+ protected <T, X> void assertNotSimilars(String message, T expected, T actual) {
+ if (expected!=actual) {
+ try {
+ assertSimilars(message,expected, actual);
+ }
+ catch(AssertionError _) {
+ // ok
+ return;
+ }
+ catch(AssertionFailedError _) {
+ // ok
+ return;
+ }
+ }
+ fail(formatFailMessage(message, expected, actual));
+ }
+
+ /** Replies if the two objects are similars.
+ *
+ * @param <T> is the type of the values
+ * @param <X> is the element's type of the values if they are arrays.
+ * @param obj1
+ * @param obj2
+ * @return <code>true</code> if the objects are similar, otherwise <code>false</code>
+ */
+ protected <T, X> boolean isSimilarObjects(T obj1, T obj2) {
+ if (obj1==obj2) return true;
+ try {
+ assertSimilars(null,obj1, obj2);
+ return true;
+ }
+ catch(AssertionError _) {
+ return false;
+ }
+ catch(AssertionFailedError _) {
+ return false;
+ }
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertDeepSimilars(Map<K,V> expectedObjects, Map<K,V> actual) {
+ assertDeepSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertDeepSimilars(String message, Map<K,V> expectedObjects, Map<K,V> actual) {
+ if (expectedObjects==actual) return;
+ if (similars(expectedObjects.keySet(), actual.keySet())) {
+ for(Entry<K,V> entry : expectedObjects.entrySet()) {
+ V v1 = entry.getValue();
+ V v2 = actual.get(entry.getKey());
+ assertSimilars(message, v1, v2);
+ }
+ // all values are correct
+ return;
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertNotDeepSimilars(Map<K,V> expectedObjects, Map<K,V> actual) {
+ assertNotDeepSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertNotDeepSimilars(String message, Map<K,V> expectedObjects, Map<K,V> actual) {
+ if (expectedObjects!=actual) {
+ if (!similars(expectedObjects.keySet(), actual.keySet())) return;
+
+ for(Entry<K,V> entry : expectedObjects.entrySet()) {
+ V v1 = entry.getValue();
+ V v2 = actual.get(entry.getKey());
+ if (!isSimilarObjects(v1, v2)) return;
+ }
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the specified value is stricly negative.
+ *
+ * @param number
+ */
+ protected void assertStrictlyNegative(Number number) {
+ assertStrictlyNegative(null,number);
+ }
+
+ /** Asserts that the specified value is stricly negative.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertStrictlyNegative(String message, Number number) {
+ if (number.doubleValue()<0.) return;
+ fail(formatFailMessage(message, "expected negative value", number)); //$NON-NLS-1$
+ }
+
+ /** Asserts that the specified value is stricly positive.
+ *
+ * @param number
+ */
+ protected void assertStrictlyPositive(Number number) {
+ assertStrictlyPositive(null,number);
+ }
+
+ /** Asserts that the specified value is stricly positive.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertStrictlyPositive(String message, Number number) {
+ if (number.doubleValue()>0.) return;
+ fail(formatFailMessage(message, "expected positive value", number)); //$NON-NLS-1$
+ }
+
+ /** Asserts that the specified value is negative.
+ *
+ * @param number
+ */
+ protected void assertNegative(Number number) {
+ assertNegative(null,number);
+ }
+
+ /** Asserts that the specified value is negative.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertNegative(String message, Number number) {
+ if (number.doubleValue()<=0.) return;
+ fail(formatFailMessage(message, "expected negative value", number)); //$NON-NLS-1$
+ }
+
+ /** Asserts that the specified value is positive.
+ *
+ * @param number
+ */
+ protected void assertPositive(Number number) {
+ assertPositive(null,number);
+ }
+
+ /** Asserts that the specified value is positive.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertPositive(String message, Number number) {
+ if (number.doubleValue()>=0.) return;
+ fail(formatFailMessage(message, "expected positive value", number)); //$NON-NLS-1$
+ }
+
+ /**
+ * Replies an array which is containing values randomly selected from the parameter.
+ * Duplicate values are allowed.
+ *
+ * @param <T> is the type of the values.
+ * @param availableValues is the collection of available values.
+ * @return the selected values (possible duplicated)
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> T[] extractRandomValues(T[] availableValues) {
+ Random rnd = new Random();
+ int count = rnd.nextInt(500);
+ ArrayList<T> tab = new ArrayList<T>(count);
+ for(int i=0; i<count; i++) {
+ tab.add(availableValues[rnd.nextInt(availableValues.length)]);
+ }
+ Class<?> clazz = availableValues.getClass().getComponentType();
+ T[] array = (T[])Array.newInstance(clazz, tab.size());
+ tab.toArray(array);
+ tab.clear();
+ return array;
+ }
+
+ /** Replies a randomized string.
+ *
+ * @return a random string.
+ */
+ protected String randomString() {
+ return randomString(-1);
+ }
+
+ /** Replies a randomized string with a max length.
+ *
+ * @param maxSize is the max length of the string.
+ * @return a random string with a max length.
+ */
+ protected String randomString(int maxSize) {
+ Random rnd = new Random();
+ StringBuffer b = new StringBuffer();
+ int count = rnd.nextInt(maxSize<=0 ? 255 : maxSize-1)+1;
+ for(int i=0; i<count; i++) {
+ char c = (char)('A' + rnd.nextInt(26));
+ b.append(c);
+ }
+ return b.toString();
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ * @param types is the parameter types of the method
+ * @param parameters is the parameter values to pass at invocation.
+ */
+ protected void assertException(Object self, String method, Class<?>[] types, Object[] parameters) {
+ assertException(null, self, method, types, parameters);
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param message is the error message to put in the assertion.
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ * @param types is the parameter types of the method
+ * @param parameters is the parameter values to pass at invocation.
+ */
+ protected void assertException(String message, Object self, String method, Class<?>[] types, Object[] parameters) {
+ try {
+ Class<?> clazz = self.getClass();
+ Method methodFunc = clazz.getMethod(method, types);
+ methodFunc.invoke(self, parameters);
+ fail((message==null ? "" : message)+"An exception was attempted but never thrown."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ catch(Exception _) {
+ // Expected behavior
+ }
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ */
+ protected void assertException(Object self, String method) {
+ assertException(null, self, method, new Class<?>[0], new Object[0]);
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param message is the error message to put in the assertion.
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ */
+ protected void assertException(String message, Object self, String method) {
+ assertException(message, self, method, new Class<?>[0], new Object[0]);
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/RepeatableTest.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/RepeatableTest.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/junit/RepeatableTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,57 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.junit;
+
+import junit.framework.Test;
+
+/** Test case that could be repeated.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public interface RepeatableTest extends Test {
+
+ /**
+ * Set the index of the current test.
+ *
+ * @param index
+ */
+ public void setLoopIndex(int index);
+
+ /**
+ * Replies the index of the current test.
+ *
+ * @return the index of the current test.
+ */
+ public int getLoopIndex();
+
+ /** Set the name of the unit test.
+ *
+ * @param name is the name of the unit test.
+ */
+ public void setName(String name);
+
+ /** Replies the name of the unit test.
+ *
+ * @return the name of the unit test.
+ */
+ public String getName();
+
+}
Added: tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,382 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import org.arakhne.junit.AbstractTestCase;
+
+/**
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public class SoftValueMapTest extends AbstractTestCase {
+
+ private static final int REFERENCE_SIZE = 0;
+
+ private final HashMap<String,String> reference = new HashMap<String,String>();
+
+ private static void collect() {
+ System.gc();System.gc();System.gc();
+ }
+
+ private void spawnReference() {
+ this.reference.clear();
+ Random rnd = new Random();
+ int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
+ String str;
+ for(int i=0; i<count; i++) {
+ str = randomString(10);
+ this.reference.put(
+ Integer.toString(i)+str,
+ str);
+ }
+ str = null;
+ }
+
+ private String getReferenceObject(int index) {
+ Object[] tab = this.reference.keySet().toArray();
+ return (String)tab[index];
+ }
+
+ private Map<String,String> removeElementsFromReference() {
+ HashMap<String,String> removed = new HashMap<String,String>();
+ Random rnd = new Random();
+ int index;
+ int count = rnd.nextInt(this.reference.size()/4)+1;
+ String key, value;
+ for(int i=0; i<count; i++) {
+ index = rnd.nextInt(this.reference.size());
+ key = getReferenceObject(index);
+ value = this.reference.remove(key);
+ removed.put(key,value);
+ }
+ key = null;
+ value = null;
+ return removed;
+ }
+
+ @Override
+ public void setUp() {
+ spawnReference();
+ }
+
+ @Override
+ public void tearDown() {
+ this.reference.clear();
+ }
+
+ /**
+ */
+ public void testSoftValueMapMap() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
+ assertDeepSimilars(this.reference, test);
+ }
+
+ /**
+ */
+ public void testSize() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>();
+ assertEquals(0, test.size());
+
+ test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertEquals(this.reference.size(), test.size());
+
+ Map<String,String> removed = removeElementsFromReference();
+ assertNotNull(removed);
+ int count = removed.size();
+ removed = null;
+
+ collect();
+
+ assertTrue(((this.reference.size()-count)<=test.size())||(this.reference.size()>test.size()));
+ }
+
+ /**
+ */
+ public void testIsEmpty() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>();
+ assertTrue(test.isEmpty());
+
+ test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertFalse(test.isEmpty());
+
+ removeElementsFromReference();
+
+ collect();
+
+ assertFalse(test.isEmpty());
+
+ this.reference.clear();
+
+ collect();
+
+ assertFalse(test.isEmpty());
+ }
+
+ /**
+ */
+ public void testContainsKey() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertDeepSimilars(this.reference, test);
+
+ // Test the content
+ {
+ String elt;
+ Iterator<String> iter = this.reference.keySet().iterator();
+ while (iter.hasNext()) {
+ elt = iter.next();
+ assertTrue(test.containsKey(elt));
+ }
+ elt = null;
+ }
+ assertDeepSimilars(this.reference, test);
+
+ Map<String,String> removedElements = removeElementsFromReference();
+ int originalSize = removedElements.size() + this.reference.size();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertEquals(originalSize, test.size());
+ assertNotDeepSimilars(this.reference, test);
+
+ // Clear the list of removed elements, which will cause collecting
+ removedElements.clear();
+ removedElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertNotEquals(this.reference.size(), test.size());
+ for(String elt : this.reference.keySet()) {
+ assertTrue(test.containsKey(elt));
+ }
+ }
+
+ /**
+ */
+ public void testContainsValue() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertDeepSimilars(this.reference, test);
+
+ // Test the content
+ {
+ String elt;
+ Iterator<String> iter = this.reference.values().iterator();
+ while (iter.hasNext()) {
+ elt = iter.next();
+ assertTrue(test.containsValue(elt));
+ }
+ elt = null;
+ }
+ assertDeepSimilars(this.reference, test);
+
+ Map<String,String> removedElements = removeElementsFromReference();
+ int originalSize = removedElements.size() + this.reference.size();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertEquals(originalSize, test.size());
+ assertNotDeepSimilars(this.reference, test);
+
+ // Clear the list of removed elements, which will cause collecting
+ removedElements.clear();
+ removedElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertNotEquals(this.reference.size(), test.size());
+ for(String elt : this.reference.values()) {
+ assertTrue(test.containsValue(elt));
+ }
+ }
+
+ /**
+ */
+ public void testEntryIterator() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(this.reference.containsKey(e.getKey()));
+ assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
+ }
+ }
+
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(baseElements.containsKey(e.getKey()));
+ assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
+ }
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
+ }
+ }
+ }
+
+ /**
+ */
+ public void testKeyIterator() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ String k;
+ Iterator<String> iter = test.keySet().iterator();
+ while (iter.hasNext()) {
+ k = iter.next();
+ assertTrue(this.reference.containsKey(k));
+ }
+ }
+
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ String k;
+ Iterator<String> iter = test.keySet().iterator();
+ while (iter.hasNext()) {
+ k = iter.next();
+ assertTrue(baseElements.containsKey(k));
+ }
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ }
+ }
+
+ /**
+ */
+ public void testValueIterator() {
+ SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ String v;
+ Iterator<String> iter = test.values().iterator();
+ while (iter.hasNext()) {
+ v = iter.next();
+ assertTrue(this.reference.containsValue(v));
+ }
+ v = null;
+ iter = null;
+ }
+
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ String v;
+ Iterator<String> iter = test.values().iterator();
+ while (iter.hasNext()) {
+ v = iter.next();
+ assertTrue(baseElements.containsValue(v));
+ }
+ v = null;
+ iter = null;
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakArrayListTest.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakArrayListTest.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakArrayListTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,931 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import org.arakhne.junit.AbstractTestCase;
+
+/**
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public class WeakArrayListTest extends AbstractTestCase {
+
+ private static final int REFERENCE_SIZE = 0;
+
+ private static void collect(WeakArrayList<String> list) {
+ for(int i=0; i<3; i++) {
+ System.gc();
+ }
+ list.expurge();
+ }
+
+ private List<String> spawnReference() {
+ Random rnd = new Random();
+ int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
+ List<String> reference = new ArrayList<String>(count);
+ for(int i=0; i<count; i++) {
+ reference.add(Integer.toString(i)+randomString(10));
+ }
+ Collections.sort(reference);
+ return reference;
+ }
+
+ /**
+ */
+ public void testWeakArrayListCollection() {
+ List<String> reference = spawnReference();
+ WeakArrayList<String> test = new WeakArrayList<String>(reference);
+ assertEquals(reference, test);
+ }
+
+ /**
+ */
+ public void testSize() {
+ List<String> reference = spawnReference();
+
+ WeakArrayList<String> test = new WeakArrayList<String>();
+ assertEquals(0, test.size());
+
+ test = new WeakArrayList<String>(reference);
+ assertEquals(reference.size(), test.size());
+
+ reference.clear();
+ reference = null;
+ collect(test);
+
+ assertEquals(0, test.size());
+ }
+
+ /**
+ */
+ public void testIsEmpty() {
+ List<String> reference = spawnReference();
+
+ WeakArrayList<String> test = new WeakArrayList<String>();
+ assertEquals(0, test.size());
+
+ test = new WeakArrayList<String>(reference);
+ assertFalse(test.isEmpty());
+
+ reference.clear();
+ reference = null;
+ collect(test);
+
+ assertTrue(test.isEmpty());
+ }
+
+// public void testContains() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// for(String elt : this.reference) {
+// assertTrue(test.contains(elt));
+// }
+// assertEquals(this.reference, test);
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// int originalSize = this.reference.size();
+// Random rnd = new Random();
+// int count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// int index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertEquals(originalSize, test.size());
+// assertNotEquals(this.reference, test);
+// for(String elt : this.reference) {
+// assertTrue(test.contains(elt));
+// }
+//
+// // Test the removed elements
+// for(String elt : removedElements) {
+// assertTrue(test.contains(elt));
+// }
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertEquals(this.reference.size(), test.size());
+// assertEquals(this.reference, test);
+// for(String elt : this.reference) {
+// assertTrue(test.contains(elt));
+// }
+// }
+//
+// public void testEquals() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// assertTrue(test.equals(this.reference));
+// assertTrue(this.reference.equals(test));
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// int originalSize = this.reference.size();
+// Random rnd = new Random();
+// int count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// int index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertEquals(originalSize, test.size());
+// assertNotEquals(this.reference, test);
+// assertFalse(test.equals(this.reference));
+// assertFalse(this.reference.equals(test));
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertEquals(this.reference.size(), test.size());
+// assertEquals(this.reference, test);
+// assertTrue(test.equals(this.reference));
+// assertTrue(this.reference.equals(test));
+// }
+//
+// public void testIterator() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// String s;
+// int idx=0;
+// Iterator<String> iter = test.iterator();
+// while (iter.hasNext()) {
+// s = iter.next();
+// assertEquals(this.reference.get(idx), s);
+// idx++;
+// }
+//
+// // Remove elements
+// ArrayList<String> baseElements = new ArrayList<String>(this.reference);
+// Random rnd = new Random();
+// int count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// int index = rnd.nextInt(this.reference.size());
+// this.reference.remove(index);
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// idx=0;
+// iter = test.iterator();
+// while (iter.hasNext()) {
+// s = iter.next();
+// assertEquals(baseElements.get(idx), s);
+// idx++;
+// }
+//
+// // Clear the list of removed elements, which will cause collecting
+// baseElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// idx=0;
+// iter = test.iterator();
+// while (iter.hasNext()) {
+// s = iter.next();
+// assertEquals(this.reference.get(idx), s);
+// idx++;
+// }
+// }
+//
+// public void testContainsAll() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// assertTrue(this.reference.containsAll(test));
+// assertTrue(test.containsAll(this.reference));
+//
+// // Remove elements
+// ArrayList<String> baseElements = new ArrayList<String>(this.reference);
+// Random rnd = new Random();
+// int count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// int index = rnd.nextInt(this.reference.size());
+// this.reference.remove(index);
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertFalse(this.reference.containsAll(test));
+// assertTrue(test.containsAll(this.reference));
+//
+// // Clear the list of removed elements, which will cause collecting
+// baseElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertTrue(this.reference.containsAll(test));
+// assertTrue(test.containsAll(this.reference));
+// }
+//
+// public void testToArray() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// assertEquals(this.reference.toArray(),test.toArray());
+//
+// // Remove elements
+// ArrayList<String> baseElements = new ArrayList<String>(this.reference);
+// Random rnd = new Random();
+// int count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// int index = rnd.nextInt(this.reference.size());
+// this.reference.remove(index);
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertNotEquals(this.reference.toArray(),test.toArray());
+//
+// // Clear the list of removed elements, which will cause collecting
+// baseElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// assertEquals(this.reference.toArray(),test.toArray());
+// }
+// public void testToArrayArray() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// String[] tab1, tab2;
+//
+// // Test the content
+// tab1 = new String[this.reference.size()];
+// this.reference.toArray(tab1);
+// tab2 = new String[test.size()];
+// test.toArray(tab2);
+// assertEquals(tab1,tab2);
+// Arrays.fill(tab1, null);
+// Arrays.fill(tab2, null);
+//
+// // Remove elements
+// ArrayList<String> baseElements = new ArrayList<String>(this.reference);
+// Collections.sort(baseElements);
+// Random rnd = new Random();
+// int count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// int index = rnd.nextInt(this.reference.size());
+// this.reference.remove(index);
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// tab1 = new String[this.reference.size()];
+// this.reference.toArray(tab1);
+// tab2 = new String[test.size()];
+// test.toArray(tab2);
+// assertNotEquals(tab1,tab2);
+// Arrays.fill(tab1, null);
+// Arrays.fill(tab2, null);
+//
+// // Clear the list of removed elements, which will cause collecting
+// baseElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// tab1 = new String[this.reference.size()];
+// this.reference.toArray(tab1);
+// tab2 = new String[test.size()];
+// test.toArray(tab2);
+// assertEquals(tab1,tab2);
+// Arrays.fill(tab1, null);
+// Arrays.fill(tab2, null);
+// }
+//
+// public void testClear() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Remove elements
+// test.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// assertTrue(test.isEmpty());
+// }
+//
+// public void testIndexOf() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// Random rnd = new Random();
+// int index;
+// int count = rnd.nextInt(this.reference.size())+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// assertEquals(index, test.indexOf(this.reference.get(index)));
+// }
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// count = rnd.nextInt(this.reference.size()/4)+1;
+// int minIndex = Integer.MAX_VALUE;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// if (index<minIndex) minIndex = index;
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// count = rnd.nextInt(this.reference.size())+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// if (index<minIndex)
+// assertEquals(index, test.indexOf(this.reference.get(index)));
+// else
+// assertFalse(index==test.indexOf(this.reference.get(index)));
+// }
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// count = rnd.nextInt(this.reference.size());
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// assertEquals(index, test.indexOf(this.reference.get(index)));
+// }
+// }
+//
+// public void testLastIndexOf() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// Random rnd = new Random();
+// int index;
+// int count = rnd.nextInt(this.reference.size())+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// assertEquals(index, test.lastIndexOf(this.reference.get(index)));
+// }
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// count = rnd.nextInt(this.reference.size()/4)+1;
+// int minIndex = Integer.MAX_VALUE;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// if (index<minIndex) minIndex = index;
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// count = rnd.nextInt(this.reference.size())+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// if (index<minIndex)
+// assertEquals(index, test.lastIndexOf(this.reference.get(index)));
+// else
+// assertFalse(index==test.lastIndexOf(this.reference.get(index)));
+// }
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// count = rnd.nextInt(this.reference.size());
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// assertEquals(index, test.lastIndexOf(this.reference.get(index)));
+// }
+// }
+//
+// public void testGetInt() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Test the content
+// Random rnd = new Random();
+// int index;
+// int count = rnd.nextInt(this.reference.size())+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// assertEquals(this.reference.get(index), test.get(index));
+// }
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// count = rnd.nextInt(this.reference.size()/4)+1;
+// int minIndex = Integer.MAX_VALUE;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// if (index<minIndex) minIndex = index;
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// count = rnd.nextInt(this.reference.size())+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// if (index<minIndex)
+// assertEquals(this.reference.get(index), test.get(index));
+// else
+// assertFalse(this.reference.get(index)==test.get(index));
+// }
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test the content
+// count = rnd.nextInt(this.reference.size());
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// assertEquals(this.reference.get(index), test.get(index));
+// }
+//
+// assertException(test, "get", new Class<?>[] {int.class}, new Object[] {test.size()}); //$NON-NLS-1$
+// }
+//
+// public void testAddE() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Add an element
+// String newElement = randomString();
+// this.reference.add(newElement);
+// test.add(newElement);
+// assertEquals(this.reference, test);
+// newElement = null;
+//
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// Random rnd = new Random();
+// int index, count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(this.reference, test);
+//
+// // Add a string without reference
+// newElement = randomString();
+// test.add(newElement);
+// newElement = null;
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(this.reference, test);
+// }
+//
+// public void testAddIntE() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// Random rnd = new Random();
+// int index, testCount, count;
+// String newElement, msg;
+//
+// testCount = rnd.nextInt(20)+5;
+//
+// for(int i=0; i<testCount; i++) {
+// msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+//
+// // Add an element
+// newElement = randomString(10);
+// index = rnd.nextInt(this.reference.size());
+// this.reference.add(index, newElement);
+// test.add(index, newElement);
+// newElement = null;
+//
+// // Test elements
+// assertEquals(msg,this.reference, test);
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int j=0; j<count; j++) {
+// index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(msg,this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+//
+// // Add a string without reference
+// newElement = randomString(10);
+// index = rnd.nextInt(test.size());
+// test.add(index, newElement);
+// newElement = null;
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+//
+// }
+// }
+//
+// public void testAddAllCollection() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Add a set of elements
+// ArrayList<String> newElements = new ArrayList<String>();
+// Random rnd = new Random();
+// int count = rnd.nextInt(20)+5;
+// for(int i=0; i<count; i++)
+// newElements.add(randomString(10));
+// this.reference.addAll(newElements);
+// test.addAll(newElements);
+// assertEquals(this.reference, test);
+// newElements.clear();
+// newElements = null;
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// int index;
+// count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int i=0; i<count; i++) {
+// index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(this.reference, test);
+//
+// // Add a string without reference
+// count = rnd.nextInt(20)+5;
+// for(int i=0; i<count; i++)
+// test.add(randomString(10));
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(this.reference, test);
+// }
+//
+// public void testAddAllIntCollection() {
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// String msg;
+// Random rnd = new Random();
+// int testCount = rnd.nextInt(20)+5;
+// int index, count, insertionIndex;
+// ArrayList<String> newElements;
+//
+// for(int i=0; i<testCount; i++) {
+// msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+// insertionIndex = rnd.nextInt(this.reference.size());
+//
+// // Add a set of elements
+// newElements = new ArrayList<String>();
+// count = rnd.nextInt(20)+5;
+// for(int j=0; j<count; j++) {
+// newElements.add(randomString(10));
+// }
+// this.reference.addAll(insertionIndex,newElements);
+// test.addAll(insertionIndex,newElements);
+// newElements.clear();
+// newElements = null;
+// assertEquals(msg,this.reference, test);
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// count = rnd.nextInt(this.reference.size()/4)+1;
+// for(int j=0; j<count; j++) {
+// index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(msg,this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+//
+// // Add a string without reference
+// count = rnd.nextInt(20)+5;
+// for(int j=0; j<count; j++)
+// test.add(randomString(10));
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+// }
+// }
+//
+// public void testSetIntE() {
+// String msg;
+// Random rnd = new Random();
+// int testCount = rnd.nextInt(20)+5;
+// int index, count, insertionIndex;
+//
+// for(int i=0; i<testCount; i++) {
+// msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+// spawnReference();
+// insertionIndex = rnd.nextInt(this.reference.size());
+//
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Add an element
+// String newElement = randomString();
+// this.reference.set(insertionIndex,newElement);
+// test.set(insertionIndex,newElement);
+// newElement = null;
+// assertEquals(msg,this.reference, test);
+//
+//
+// // Remove elements
+// ArrayList<String> removedElements = new ArrayList<String>();
+// rnd = new Random();
+// count = rnd.nextInt(this.reference.size()/4+1)+1;
+// for(int j=0; j<count; j++) {
+// index = rnd.nextInt(this.reference.size());
+// removedElements.add(this.reference.remove(index));
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(msg,this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// removedElements.clear();
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+//
+// // Add a string without reference
+// if (!test.isEmpty()) {
+// newElement = randomString();
+// insertionIndex = rnd.nextInt(test.size());
+// test.set(insertionIndex,newElement);
+// newElement = null;
+// }
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(msg,this.reference, test);
+// }
+// }
+//
+// public void testRemoveObject() {
+// String msg;
+// Random rnd = new Random();
+// int testCount = rnd.nextInt(20)+5;
+// int removalIndex;
+//
+// for(int i=0; i<testCount; i++) {
+// msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+// spawnReference();
+// removalIndex = rnd.nextInt(this.reference.size());
+//
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Remove elements
+// test.remove(this.reference.get(removalIndex));
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(msg,this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// this.reference.remove(removalIndex);
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+// }
+// }
+//
+// public void testRemoveInt() {
+// String msg;
+// Random rnd = new Random();
+// int testCount = rnd.nextInt(20)+5;
+// int removalIndex;
+//
+// for(int i=0; i<testCount; i++) {
+// msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+// spawnReference();
+// removalIndex = rnd.nextInt(this.reference.size());
+//
+// WeakArrayList<String> test = new WeakArrayList<String>(this.reference);
+// assertEquals(this.reference, test);
+//
+// // Remove elements
+// test.remove(removalIndex);
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertNotEquals(msg,this.reference, test);
+//
+// // Clear the list of removed elements, which will cause collecting
+// this.reference.remove(removalIndex);
+//
+// // Collects the objects
+// collect(test);
+//
+// // Test content
+// assertEquals(msg,this.reference, test);
+// }
+// }
+//
+ /**
+ */
+ public void testHashCode() {
+ List<String> reference = spawnReference();
+ WeakArrayList<String> test = new WeakArrayList<String>(reference);
+ assertEquals(reference, test);
+
+ assertEquals(reference.hashCode(),test.hashCode());
+
+ // Remove elements
+ reference.clear();
+
+ // Collects the objects
+ collect(test);
+
+ // Test the content
+ assertNotEquals(hashCode(), test.hashCode());
+ }
+
+ /**
+ */
+ public void testListener() {
+ Listener listener = new Listener();
+ WeakArrayList<String> list = new WeakArrayList<String>();
+ list.addReferenceListener(listener);
+
+ Random rnd = new Random();
+ int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
+ for(int i=0; i<count; i++) {
+ list.add(randomString());
+ }
+
+ assertFalse(list.isEmpty());
+
+ collect(list);
+
+ assertTrue(list.isEmpty());
+ assertEquals(count, listener.count);
+
+ }
+
+ private class Listener implements ReferenceListener {
+
+ public int count = 0;
+
+ public Listener() {
+ //
+ }
+
+ @Override
+ public void referenceReleased(int released) {
+ this.count += released;
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
===================================================================
--- tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java (rev 0)
+++ tags/afc-2.0/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,399 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import org.arakhne.junit.AbstractTestCase;
+
+/**
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public class WeakValueMapTest extends AbstractTestCase {
+
+ private static final int REFERENCE_SIZE = 0;
+
+ private final HashMap<String,String> reference = new HashMap<String,String>();
+
+ private static void collect() {
+ System.gc();System.gc();System.gc();
+ }
+
+ private void spawnReference() {
+ this.reference.clear();
+ Random rnd = new Random();
+ int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
+ String str;
+ for(int i=0; i<count; i++) {
+ str = randomString(10);
+ this.reference.put(
+ Integer.toString(i)+str,
+ str);
+ }
+ str = null;
+ }
+
+ private String getReferenceObject(int index) {
+ Object[] tab = this.reference.keySet().toArray();
+ return (String)tab[index];
+ }
+
+ private Map<String,String> removeElementsFromReference() {
+ HashMap<String,String> removed = new HashMap<String,String>();
+ Random rnd = new Random();
+ int index;
+ int count = rnd.nextInt(this.reference.size()/4)+1;
+ String key, value;
+ for(int i=0; i<count; i++) {
+ index = rnd.nextInt(this.reference.size());
+ key = getReferenceObject(index);
+ value = this.reference.remove(key);
+ removed.put(key,value);
+ }
+ key = null;
+ value = null;
+ return removed;
+ }
+
+ @Override
+ public void setUp() {
+ spawnReference();
+ }
+
+ @Override
+ public void tearDown() {
+ this.reference.clear();
+ }
+
+ /**
+ */
+ public void testEntryIterator() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(this.reference.containsKey(e.getKey()));
+ assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
+ }
+ }
+
+ {
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(baseElements.containsKey(e.getKey()));
+ assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
+ }
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+ collect();
+ }
+
+ // Test the content
+ /*{
+ assertDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(this.reference.containsKey(e.getKey()));
+ assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
+ }
+ }*/
+ }
+
+ /**
+ */
+ public void testWeakValueMapMap() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ assertDeepSimilars(this.reference, test);
+ }
+
+ /**
+ */
+ public void testSize() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>();
+ assertEquals(0, test.size());
+
+ test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertEquals(this.reference.size(), test.size());
+
+ removeElementsFromReference();
+
+ collect();
+
+ assertEquals(this.reference.size(), test.size());
+ }
+
+ /**
+ */
+ public void testIsEmpty() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>();
+ assertTrue(test.isEmpty());
+
+ test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertFalse(test.isEmpty());
+
+ removeElementsFromReference();
+
+ collect();
+
+ assertFalse(test.isEmpty());
+
+ this.reference.clear();
+
+ collect();
+
+ assertTrue(test.isEmpty());
+ }
+
+ /**
+ */
+ public void testContainsKey() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertDeepSimilars(this.reference, test);
+
+ // Test the content
+ {
+ String elt;
+ Iterator<String> iter = this.reference.keySet().iterator();
+ while (iter.hasNext()) {
+ elt = iter.next();
+ assertTrue(test.containsKey(elt));
+ }
+ elt = null;
+ }
+ assertDeepSimilars(this.reference, test);
+
+ Map<String,String> removedElements = removeElementsFromReference();
+ int originalSize = removedElements.size() + this.reference.size();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertEquals(originalSize, test.size());
+ assertNotDeepSimilars(this.reference, test);
+
+ // Clear the list of removed elements, which will cause collecting
+ removedElements.clear();
+ removedElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertEquals(this.reference.size(), test.size());
+ assertDeepSimilars(this.reference, test);
+ for(String elt : this.reference.keySet()) {
+ assertTrue(test.containsKey(elt));
+ }
+ }
+
+ /**
+ */
+ public void testContainsValue() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+ assertDeepSimilars(this.reference, test);
+
+ // Test the content
+ {
+ String elt;
+ Iterator<String> iter = this.reference.values().iterator();
+ while (iter.hasNext()) {
+ elt = iter.next();
+ assertTrue(test.containsValue(elt));
+ }
+ elt = null;
+ }
+ assertDeepSimilars(this.reference, test);
+
+ Map<String,String> removedElements = removeElementsFromReference();
+ int originalSize = removedElements.size() + this.reference.size();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertEquals(originalSize, test.size());
+ assertNotDeepSimilars(this.reference, test);
+
+ // Clear the list of removed elements, which will cause collecting
+ removedElements.clear();
+ removedElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ assertEquals(this.reference.size(), test.size());
+ assertDeepSimilars(this.reference, test);
+ for(String elt : this.reference.values()) {
+ assertTrue(test.containsValue(elt));
+ }
+ }
+
+ /**
+ */
+ public void testKeyIterator() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ String k;
+ Iterator<String> iter = test.keySet().iterator();
+ while (iter.hasNext()) {
+ k = iter.next();
+ assertTrue(this.reference.containsKey(k));
+ }
+ }
+
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ String k;
+ Iterator<String> iter = test.keySet().iterator();
+ while (iter.hasNext()) {
+ k = iter.next();
+ assertTrue(baseElements.containsKey(k));
+ }
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ String k;
+ Iterator<String> iter = test.keySet().iterator();
+ while (iter.hasNext()) {
+ k = iter.next();
+ assertTrue(this.reference.containsKey(k));
+ }
+ }
+ }
+
+ /**
+ */
+ public void testValueIterator() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ String v;
+ Iterator<String> iter = test.values().iterator();
+ while (iter.hasNext()) {
+ v = iter.next();
+ assertTrue(this.reference.containsValue(v));
+ }
+ v = null;
+ iter = null;
+ }
+
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ String v;
+ Iterator<String> iter = test.values().iterator();
+ while (iter.hasNext()) {
+ v = iter.next();
+ assertTrue(baseElements.containsValue(v));
+ }
+ v = null;
+ iter = null;
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ String v;
+ Iterator<String> iter = test.values().iterator();
+ while (iter.hasNext()) {
+ v = iter.next();
+ assertTrue(this.reference.containsValue(v));
+ }
+ v = null;
+ iter = null;
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/bin.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/bin.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/bin.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,36 @@
+<assembly>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <moduleSets>
+ <moduleSet>
+ <includeSubModules>false</includeSubModules>
+ <includes>
+ <include>org.arakhne.afc:arakhneVmutils-java</include>
+ </includes>
+ <binaries>
+ <outputDirectory></outputDirectory>
+ <unpack>true</unpack>
+ <includeDependencies>false</includeDependencies>
+ </binaries>
+ </moduleSet>
+ </moduleSets>
+ <files>
+ <file>
+ <source>native/josuuid/linux32/target/josuuid-linux32.so</source>
+ <outputDirectory>org/arakhne/vmutil</outputDirectory>
+ <destName>libjosuuid32.so</destName>
+ </file>
+ <file>
+ <source>native/josuuid/linux64/target/josuuid-linux64.so</source>
+ <outputDirectory>org/arakhne/vmutil</outputDirectory>
+ <destName>libjosuuid64.so</destName>
+ </file>
+ <file>
+ <source>native/josuuid/mingw/target/josuuid-mingw.dll</source>
+ <outputDirectory>org/arakhne/vmutil</outputDirectory>
+ <destName>josuuid32.dll</destName>
+ </file>
+ </files>
+</assembly>
Added: tags/afc-2.0/arakhneVmutils/java/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>afc</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>2.0</version>
+ </parent>
+
+ <artifactId>arakhneVmutils-java</artifactId>
+ <packaging>jar</packaging>
+ <groupId>org.arakhne.afc</groupId>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/AutoboxingUtil.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/AutoboxingUtil.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/AutoboxingUtil.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,226 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2008 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * This utility class provides a way to extend the Class class
+ * with autoboxing-compliant functions.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @since since JDK 1.5
+ * @deprecated see {@link ReflectionUtil}
+ */
+@Deprecated
+public class AutoboxingUtil {
+
+ /**
+ * Determines if the specified <code>Object</code> is assignment-compatible
+ * with the object represented by the <code>Class</code>. This method extends
+ * {@link Class#isInstance(Object)} with autoboxing support.
+ *
+ * @param type is the class against which the object must be test
+ * @param obj is the object to check
+ * @return <code>true</code> if <code>obj</code> is an instance of the type
+ * @see Class#isInstance(Object)
+ */
+ public static boolean isInstance(Class<?> type, Object obj) {
+ assert(type!=null);
+ if (obj==null) return false;
+
+ // Test according to the Class's behaviour
+ if (type.isInstance(obj)) return true;
+
+ // Test according to autoboxing
+ if (type.isPrimitive()
+ &&
+ type!=Void.class && type!=void.class) {
+
+ if (type==Boolean.class) return boolean.class.isInstance(obj);
+ if (type==boolean.class) return Boolean.class.isInstance(obj);
+
+ if (type==Character.class) return char.class.isInstance(obj);
+ if (type==char.class) return Character.class.isInstance(obj);
+
+ if (type==Byte.class) return byte.class.isInstance(obj);
+ if (type==byte.class) return Byte.class.isInstance(obj);
+
+ if (type==Short.class) return short.class.isInstance(obj);
+ if (type==short.class) return Short.class.isInstance(obj);
+
+ if (type==Integer.class) return int.class.isInstance(obj);
+ if (type==int.class) return Integer.class.isInstance(obj);
+
+ if (type==Long.class) return long.class.isInstance(obj);
+ if (type==long.class) return Long.class.isInstance(obj);
+
+ if (type==Float.class) return float.class.isInstance(obj);
+ if (type==float.class) return Float.class.isInstance(obj);
+
+ if (type==Double.class) return double.class.isInstance(obj);
+ if (type==double.class) return Double.class.isInstance(obj);
+
+ if (type==Void.class) return void.class.isInstance(obj);
+ if (type==void.class) return Void.class.isInstance(obj);
+
+ assert false: "Unsupported primitive type"; //$NON-NLS-1$
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Determines if the <code>assignmentTarget</code> object is either the same as,
+ * or is a superclass or superinterface of, the class or interface
+ * represented by the specified
+ * <code>assignementSource</code> parameter. This method extends
+ * {@link Class#isAssignableFrom(Class)} with autoboxing support.
+ *
+ * @param assignementTarget is the class that is tested to be a super class.
+ * @param assignementSource is the class that is tested to be a sub class.
+ * @return <code>true</code> if an object of the <var>assignementSource</var> type
+ * could be assigned to a variable of <var>assignementTarget</var> type,
+ * otherwise <code>false</code>.
+ */
+ public static boolean isAssignableFrom(Class<?> assignementTarget, Class<?> assignementSource) {
+ assert(assignementSource!=null);
+ assert(assignementTarget!=null);
+
+ // Test according to the Class's behaviour
+ if (assignementTarget.isAssignableFrom(assignementSource)) return true;
+
+ // Test according to autoboxing
+ if (assignementTarget.isPrimitive() && assignementSource.isPrimitive()
+ &&
+ assignementTarget!=Void.class && assignementTarget!=void.class
+ &&
+ assignementSource!=Void.class && assignementSource!=void.class) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /** Replies the type that corresponds to the specified class.
+ * If the name corresponds to a primitive type, the low-level type
+ * will be replied.
+ * This method extends
+ * {@link Class#forName(String)} with autoboxing support.
+ *
+ * @param name is the name of the class to load.
+ * @return the loaded class
+ * @throws ClassNotFoundException if name names an
+ * unknown class or primitive
+ */
+ public static Class<?> forName(String name) throws ClassNotFoundException {
+ if (name == null || "".equals(name) || "null".equals(name) || "void".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return void.class;
+ }
+ if ("boolean".equals(name)) { //$NON-NLS-1$
+ return boolean.class;
+ }
+ if ("byte".equals(name)) { //$NON-NLS-1$
+ return byte.class;
+ }
+ if ("char".equals(name)) { //$NON-NLS-1$
+ return char.class;
+ }
+ if ("double".equals(name)) { //$NON-NLS-1$
+ return double.class;
+ }
+ if ("float".equals(name)) { //$NON-NLS-1$
+ return float.class;
+ }
+ if ("int".equals(name)) { //$NON-NLS-1$
+ return int.class;
+ }
+ if ("long".equals(name)) { //$NON-NLS-1$
+ return long.class;
+ }
+ if ("short".equals(name)) { //$NON-NLS-1$
+ return short.class;
+ }
+ return Class.forName(name);
+ }
+
+ /** Replies the type that corresponds to the specified class.
+ * If the name corresponds to a primitive type, the low-level type
+ * will be replied.
+ * This method extends
+ * {@link Class#forName(String)} with autoboxing support.
+ *
+ * @param name is the name of the class to load.
+ * @param loader is the class loader to use.
+ * @return the loaded class
+ * @throws ClassNotFoundException if name names an
+ * unknown class or primitive
+ */
+ public static Class<?> forName(String name, ClassLoader loader) throws ClassNotFoundException {
+ return forName(name, true, loader);
+ }
+
+ /** Replies the type that corresponds to the specified class.
+ * If the name corresponds to a primitive type, the low-level type
+ * will be replied.
+ * This method extends
+ * {@link Class#forName(String)} with autoboxing support.
+ *
+ * @param name is the name of the class to load.
+ * @param typeInitialization must be <code>true</code> to initialize the type, <code>false</code> otherwise.
+ * @param loader is the class loader to use.
+ * @return the loaded class
+ * @throws ClassNotFoundException if name names an
+ * unknown class or primitive
+ */
+ public static Class<?> forName(String name, boolean typeInitialization, ClassLoader loader) throws ClassNotFoundException {
+ if (name == null || "".equals(name) || "null".equals(name) || "void".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return void.class;
+ }
+ if ("boolean".equals(name)) { //$NON-NLS-1$
+ return boolean.class;
+ }
+ if ("byte".equals(name)) { //$NON-NLS-1$
+ return byte.class;
+ }
+ if ("char".equals(name)) { //$NON-NLS-1$
+ return char.class;
+ }
+ if ("double".equals(name)) { //$NON-NLS-1$
+ return double.class;
+ }
+ if ("float".equals(name)) { //$NON-NLS-1$
+ return float.class;
+ }
+ if ("int".equals(name)) { //$NON-NLS-1$
+ return int.class;
+ }
+ if ("long".equals(name)) { //$NON-NLS-1$
+ return long.class;
+ }
+ if ("short".equals(name)) { //$NON-NLS-1$
+ return short.class;
+ }
+ return Class.forName(name, typeInitialization, loader);
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Caller.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Caller.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Caller.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2008 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import sun.reflect.Reflection;
+
+/**
+ * This utility class provides a way to determine which class
+ * call a function.
+ * <p>
+ * It inspirated from the Sun's <code>sun.reflect.Reflection</code> class
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-04-25 13:08:07 $
+ */
+@SuppressWarnings("restriction")
+public class Caller {
+
+ /** Replies the class of the caller that invoked the function
+ * from which <code>GetCallerClass()</code> was invoked.
+ *
+ * @return the class of the caller that invoked the function
+ * from which <code>GetCallerClass()</code> was invoked.
+ */
+ public static Class<?> getCallerClass() {
+ // Parameter value:
+ // 0: is the top from the trace stack (Reflection.class)
+ // 1: is the second top from the trace stack (Caller.class)
+ // 2: is the third top of the trace stack ie, the caller of this function
+ // 3: is the fourth top of the trace stack ie, the caller of invoked function in step 2
+ return Reflection.getCallerClass(3);
+ }
+
+ /** Replies the class from the stack according to its level.
+ * <p>
+ * The given <var>level</var> permits to specify which class to reply:
+ * <ul>
+ * <li><code>0</code>: the class where is defined the function (<code>f<sub>0</sub></code>)
+ * that has called <code>getCallerClass()</code></li>
+ * <li><code>1</code>: the class where is defined the function (<code>f<sub>1</sub></code>)
+ * that has called <code>f<sub>0</sub></code></li>
+ * <li><code>1</code>: the class where is defined the function (<code>f<sub>2</sub></code>)
+ * that has called <code>f<sub>1</sub></code></li>
+ * <li>etc.</li>
+ * </ul>
+ *
+ * @param level is the desired level of the class
+ * @return the class from the call stack according to the given level.
+ */
+ public static Class<?> getCallerClass(int level) {
+ if (level<0) throw new IllegalArgumentException();
+ // Parameter value:
+ // 0: is the top from the trace stack (Reflection.class)
+ // 1: is the second top from the trace stack (Caller.class)
+ // 2: is the third top of the trace stack ie, the caller of this function
+ // 3: is the fourth top of the trace stack ie, the caller of invoked function in step 2
+ return Reflection.getCallerClass(level+2);
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,101 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2008 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * This utility class permits to find the better class loader
+ * for your application.
+ * <p>
+ * It tries to find the preferred class loader registered with
+ * {@link #setPreferredClassLoader(ClassLoader)}.
+ * If none was found, the default class loader will be replied.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:43:41 $
+ */
+public final class ClassLoaderFinder {
+
+ private static volatile ClassLoader __dyn_loader = null;
+
+ /**
+ * Replies the better class loader.
+ * <p>
+ * It tries to find the preferred class loader.
+ * If none was found, the default class loader will be replied.
+ *
+ * @return the class loader, never <code>null</code>
+ */
+ public static ClassLoader findClassLoader() {
+
+ if (__dyn_loader==null)
+ return ClassLoaderFinder.class.getClassLoader();
+ return __dyn_loader;
+ }
+
+ /**
+ * Set the preferred class loader.
+ *
+ * @param class_loader is the preferred class loader
+ */
+ public static void setPreferredClassLoader(ClassLoader class_loader) {
+ if (class_loader!=__dyn_loader) {
+ __dyn_loader = class_loader;
+ Thread[] threads = new Thread[Thread.activeCount()];
+ Thread.enumerate(threads);
+ for(Thread t : threads) {
+ if (t!=null)
+ t.setContextClassLoader(class_loader);
+ }
+ }
+ }
+
+ /**
+ * Pop the preferred class loader.
+ */
+ public static void popPreferredClassLoader() {
+ ClassLoader sysLoader = ClassLoaderFinder.class.getClassLoader();
+
+ if ((__dyn_loader==null)||
+ (__dyn_loader==sysLoader)) {
+ __dyn_loader = null;
+ Thread[] threads = new Thread[Thread.activeCount()];
+ Thread.enumerate(threads);
+ for(Thread t : threads) {
+ if (t!=null)
+ t.setContextClassLoader(sysLoader);
+ }
+ return;
+ }
+
+ ClassLoader parent = __dyn_loader.getParent();
+
+ __dyn_loader = (parent==sysLoader) ? null : parent;
+
+ Thread[] threads = new Thread[Thread.activeCount()];
+ Thread.enumerate(threads);
+ for(Thread t : threads) {
+ if (t!=null)
+ t.setContextClassLoader(parent);
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,583 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2008 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes.Name;
+
+import sun.misc.Resource;
+import sun.misc.URLClassPath;
+import sun.net.www.ParseUtil;
+import sun.security.util.SecurityConstants;
+
+/** This class loader permits to load classes from
+ * a set of classpaths.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.2 $ $Date: 2007-04-10 08:35:33 $
+ */
+@SuppressWarnings("restriction")
+public class DynamicURLClassLoader extends SecureClassLoader {
+
+ /**
+ * The search path for classes and resources.
+ */
+ protected URLClassPath _ucp;
+
+ /**
+ * The context to be used when loading classes and resources
+ */
+ protected AccessControlContext _acc;
+
+ /**
+ * Constructs a new ClassPathClassLoader for the given URLs. The URLs will be
+ * searched in the order specified for classes and resources after first
+ * searching in the specified parent class loader. Any URL that ends with
+ * a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
+ * to refer to a JAR file which will be downloaded and opened as needed.
+ *
+ * <p>If there is a security manager, this method first
+ * calls the security manager's <code>checkCreateClassLoader</code> method
+ * to ensure creation of a class loader is allowed.
+ *
+ * @param parent the parent class loader for delegation
+ * @param acc is the current access context
+ * @param urls the URLs from which to load classes and resources
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkCreateClassLoader</code> method doesn't allow
+ * creation of a class loader.
+ * @see SecurityManager#checkCreateClassLoader
+ */
+ protected DynamicURLClassLoader(ClassLoader parent, AccessControlContext acc, URL... urls) {
+ super(parent);
+ // this is to make the stack depth consistent with 1.1
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkCreateClassLoader();
+ }
+ this._ucp = new URLClassPath(mergeClassPath(urls));
+ this._acc = acc;
+ }
+
+ /**
+ * Appends the specified URL to the list of URLs to search for
+ * classes and resources.
+ *
+ * @param url the URL to be added to the search path of URLs
+ */
+ public void addURL(final URL url) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ DynamicURLClassLoader.this._ucp.addURL(url);
+ return null;
+ }
+ }, this._acc);
+ }
+
+ /**
+ * Appends the specified URL to the list of URLs to search for
+ * classes and resources.
+ *
+ * @param urls the URLs to be added to the search path of URLs
+ */
+ public void addURLs(URL... urls) {
+ for (URL url : urls) {
+ addURL(url);
+ }
+ }
+
+ /**
+ * Appends the specified URL to the list of URLs to search for
+ * classes and resources.
+ *
+ * @param urls the URL to be added to the search path of URLs
+ */
+ public void removeURLs(URL... urls) {
+ HashSet<URL> set = new HashSet<URL>();
+ set.addAll(Arrays.asList(this._ucp.getURLs()));
+ set.removeAll(Arrays.asList(urls));
+ URL[] tab = new URL[set.size()];
+ set.toArray(tab);
+ this._ucp = new URLClassPath(tab);
+ tab = null;
+ }
+
+ /**
+ * Appends the specified URL to the list of URLs to search for
+ * classes and resources.
+ *
+ * @param url the URL to be added to the search path of URLs
+ */
+ public void removeURL(URL url) {
+ removeURLs(url);
+ }
+
+ /**
+ * Returns the search path of URLs for loading classes and resources.
+ * This includes the original list of URLs specified to the constructor,
+ * along with any URLs subsequently appended by the addURL() method.
+ * @return the search path of URLs for loading classes and resources.
+ */
+ public URL[] getURLs() {
+ return this._ucp.getURLs();
+ }
+
+ /**
+ * Finds and loads the class with the specified name from the URL search
+ * path. Any URLs referring to JAR files are loaded and opened as needed
+ * until the class is found.
+ *
+ * @param name the name of the class
+ * @return the resulting class
+ * @exception ClassNotFoundException if the class could not be found
+ */
+ @Override
+ protected Class<?> findClass(final String name) throws ClassNotFoundException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+ public Class<?> run() throws ClassNotFoundException {
+ String path = name.replace('.', '/').concat(".class"); //$NON-NLS-1$
+ Resource res = DynamicURLClassLoader.this._ucp.getResource(path, false);
+ if (res != null) {
+ try {
+ return defineClass(name, res);
+ }
+ catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
+ throw new ClassNotFoundException(name);
+ }
+ }, this._acc);
+ }
+ catch (java.security.PrivilegedActionException pae) {
+ throw (ClassNotFoundException) pae.getException();
+ }
+ }
+
+ /**
+ * Defines a Class using the class bytes obtained from the specified
+ * Resource. The resulting Class must be resolved before it can be
+ * used.
+ *
+ * @param name is the name of the class to define
+ * @param res is the resource from which the class byte-code could be obtained
+ * @return the loaded class.
+ * @throws IOException in case the byte-code was unavailable.
+ */
+ protected Class<?> defineClass(String name, Resource res) throws IOException {
+ int i = name.lastIndexOf('.');
+ URL url = res.getCodeSourceURL();
+ if (i != -1) {
+ String pkgname = name.substring(0, i);
+ // Check if package already loaded.
+ Package pkg = getPackage(pkgname);
+ Manifest man = res.getManifest();
+ if (pkg != null) {
+ // Package found, so check package sealing.
+ if (pkg.isSealed()) {
+ // Verify that code source URL is the same.
+ if (!pkg.isSealed(url)) {
+ throw new SecurityException(
+ "sealing violation: package " + pkgname + " is sealed"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ } else {
+ // Make sure we are not attempting to seal the package
+ // at this code source URL.
+ if ((man != null) && isSealed(pkgname, man)) {
+ throw new SecurityException(
+ "sealing violation: can't seal package " + pkgname + //$NON-NLS-1$
+ ": already loaded"); //$NON-NLS-1$
+ }
+ }
+ } else {
+ if (man != null) {
+ definePackage(pkgname, man, url);
+ } else {
+ definePackage(pkgname, null, null, null, null, null, null, null);
+ }
+ }
+ }
+ // Now read the class bytes and define the class
+ java.nio.ByteBuffer bb = res.getByteBuffer();
+ if (bb != null) {
+ // Use (direct) ByteBuffer:
+ CodeSigner[] signers = res.getCodeSigners();
+ CodeSource cs = new CodeSource(url, signers);
+ return defineClass(name, bb, cs);
+ }
+
+ byte[] b = res.getBytes();
+ // must read certificates AFTER reading bytes.
+ CodeSigner[] signers = res.getCodeSigners();
+ CodeSource cs = new CodeSource(url, signers);
+ return defineClass(name, b, 0, b.length, cs);
+
+ }
+
+ /**
+ * Defines a new package by name in this ClassLoader. The attributes
+ * contained in the specified Manifest will be used to obtain package
+ * version and sealing information. For sealed packages, the additional
+ * URL specifies the code source URL from which the package was loaded.
+ *
+ * @param name the package name
+ * @param man the Manifest containing package version and sealing
+ * information
+ * @param url the code source url for the package, or null if none
+ * @exception IllegalArgumentException if the package name duplicates
+ * an existing package either in this class loader or one
+ * of its ancestors
+ * @return the newly defined Package object
+ */
+ protected Package definePackage(String name, Manifest man, URL url)
+ throws IllegalArgumentException
+ {
+ String path = name.replace('.', '/').concat("/"); //$NON-NLS-1$
+ String specTitle = null, specVersion = null, specVendor = null;
+ String implTitle = null, implVersion = null, implVendor = null;
+ String sealed = null;
+ URL sealBase = null;
+
+ Attributes attr = man.getAttributes(path);
+ if (attr != null) {
+ specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+ specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+ specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+ implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+ implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+ implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+ sealed = attr.getValue(Name.SEALED);
+ }
+ attr = man.getMainAttributes();
+ if (attr != null) {
+ if (specTitle == null) {
+ specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+ }
+ if (specVersion == null) {
+ specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+ }
+ if (specVendor == null) {
+ specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+ }
+ if (implTitle == null) {
+ implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+ }
+ if (implVersion == null) {
+ implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+ }
+ if (implVendor == null) {
+ implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+ }
+ if (sealed == null) {
+ sealed = attr.getValue(Name.SEALED);
+ }
+ }
+ if ("true".equalsIgnoreCase(sealed)) { //$NON-NLS-1$
+ sealBase = url;
+ }
+ return definePackage(name, specTitle, specVersion, specVendor,
+ implTitle, implVersion, implVendor, sealBase);
+ }
+
+ /*
+ * Returns true if the specified package name is sealed according to the
+ * given manifest.
+ */
+ private boolean isSealed(String name, Manifest man) {
+ String path = name.replace('.', '/').concat("/"); //$NON-NLS-1$
+ Attributes attr = man.getAttributes(path);
+ String sealed = null;
+ if (attr != null) {
+ sealed = attr.getValue(Name.SEALED);
+ }
+ if (sealed == null) {
+ if ((attr = man.getMainAttributes()) != null) {
+ sealed = attr.getValue(Name.SEALED);
+ }
+ }
+ return "true".equalsIgnoreCase(sealed); //$NON-NLS-1$
+ }
+
+ /**
+ * Finds the resource with the specified name on the URL search path.
+ *
+ * @param name the name of the resource
+ * @return a <code>URL</code> for the resource, or <code>null</code>
+ * if the resource could not be found.
+ */
+ @Override
+ public URL findResource(final String name) {
+ /*
+ * The same restriction to finding classes applies to resources
+ */
+ URL url =
+ AccessController.doPrivileged(new PrivilegedAction<URL>() {
+ public URL run() {
+ return DynamicURLClassLoader.this._ucp.findResource(name, true);
+ }
+ }, this._acc);
+
+ return url != null ? this._ucp.checkURL(url) : null;
+ }
+
+ /**
+ * Returns an Enumeration of URLs representing all of the resources
+ * on the URL search path having the specified name.
+ *
+ * @param name the resource name
+ * @exception IOException if an I/O exception occurs
+ * @return an <code>Enumeration</code> of <code>URL</code>s
+ */
+ @Override
+ public Enumeration<URL> findResources(final String name) throws IOException {
+ final Enumeration<?> e = this._ucp.findResources(name, true);
+
+ return new Enumeration<URL>() {
+ private URL url = null;
+
+ private boolean next() {
+ if (this.url != null) {
+ return true;
+ }
+ do {
+ URL u = AccessController.doPrivileged(new PrivilegedAction<URL>() {
+ public URL run() {
+ if (!e.hasMoreElements())
+ return null;
+ return (URL)e.nextElement();
+ }
+ }, DynamicURLClassLoader.this._acc);
+ if (u == null) break;
+ this.url = DynamicURLClassLoader.this._ucp.checkURL(u);
+ }
+ while (this.url == null);
+
+ return (this.url != null);
+ }
+
+ public URL nextElement() {
+ if (!next()) {
+ throw new NoSuchElementException();
+ }
+ URL u = this.url;
+ this.url = null;
+ return u;
+ }
+
+ public boolean hasMoreElements() {
+ return next();
+ }
+ };
+ }
+
+ /**
+ * Returns the permissions for the given codesource object.
+ * The implementation of this method first calls super.getPermissions
+ * and then adds permissions based on the URL of the codesource.
+ * <p>
+ * If the protocol is "file"
+ * and the path specifies a file, then permission to read that
+ * file is granted. If protocol is "file" and the path is
+ * a directory, permission is granted to read all files
+ * and (recursively) all files and subdirectories contained in
+ * that directory.
+ * <p>
+ * If the protocol is not "file", then
+ * to connect to and accept connections from the URL's host is granted.
+ * @param codesource the codesource
+ * @return the permissions granted to the codesource
+ */
+ @Override
+ protected PermissionCollection getPermissions(CodeSource codesource) {
+ PermissionCollection perms = super.getPermissions(codesource);
+
+ URL url = codesource.getLocation();
+
+ Permission p;
+ URLConnection urlConnection;
+
+ try {
+ urlConnection = url.openConnection();
+ p = urlConnection.getPermission();
+ }
+ catch (java.io.IOException ioe) {
+ p = null;
+ urlConnection = null;
+ }
+
+ if ((p!=null)&&(p instanceof FilePermission)) {
+ // if the permission has a separator char on the end,
+ // it means the codebase is a directory, and we need
+ // to add an additional permission to read recursively
+ String path = p.getName();
+ if (path.endsWith(File.separator)) {
+ path += "-"; //$NON-NLS-1$
+ p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
+ }
+ }
+ else if ((p == null) && (url.getProtocol().equals("file"))) { //$NON-NLS-1$
+ String path = url.getFile().replace('/', File.separatorChar);
+ path = ParseUtil.decode(path);
+ if (path.endsWith(File.separator))
+ path += "-"; //$NON-NLS-1$
+ p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
+ }
+ else {
+ URL locUrl = url;
+ if (urlConnection instanceof JarURLConnection) {
+ locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
+ }
+ String host = locUrl.getHost();
+ if (host == null)
+ host = "localhost"; //$NON-NLS-1$
+ p = new SocketPermission(host,
+ SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION);
+ }
+
+ // make sure the person that created this class loader
+ // would have this permission
+
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ final Permission fp = p;
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() throws SecurityException {
+ sm.checkPermission(fp);
+ return null;
+ }
+ }, this._acc);
+ }
+ perms.add(p);
+
+ return perms;
+ }
+
+ /**
+ * Creates a new instance of DynamicURLClassLoader for the specified
+ * URLs and parent class loader. If a security manager is
+ * installed, the <code>loadClass</code> method of the URLClassLoader
+ * returned by this method will invoke the
+ * <code>SecurityManager.checkPackageAccess</code> method before
+ * loading the class.
+ *
+ * @param parent the parent class loader for delegation
+ * @param urls the URLs to search for classes and resources
+ * @return the resulting class loader
+ */
+ public static DynamicURLClassLoader newInstance(final ClassLoader parent, final URL... urls) {
+ // Save the caller's context
+ final AccessControlContext acc = AccessController.getContext();
+ // Need a privileged block to create the class loader
+ DynamicURLClassLoader ucl =
+ AccessController.doPrivileged(new PrivilegedAction<DynamicURLClassLoader>() {
+ public DynamicURLClassLoader run() {
+ // Now set the context on the loader using the one we saved,
+ // not the one inside the privileged block...
+ return new FactoryDynamicURLClassLoader(parent, acc, urls);
+ }
+ });
+ return ucl;
+ }
+
+ /**
+ * Merge the specified URLs to the current classpath.
+ */
+ private static URL[] mergeClassPath(URL... urls) {
+ String path = System.getProperty("java.class.path"); //$NON-NLS-1$
+ String separator = System.getProperty("path.separator"); //$NON-NLS-1$
+ String[] parts = path.split(separator);
+ URL[] u = new URL[parts.length+urls.length];
+ for(int i=0; i<parts.length; i++) {
+ try {
+ u[i] = new File(parts[i]).toURI().toURL();
+ }
+ catch (MalformedURLException _) {
+ // ignore exception
+ }
+ }
+ System.arraycopy(urls,0,u,parts.length,urls.length);
+ return u;
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.2 $ $Date: 2007-04-10 08:35:33 $
+ */
+ protected final static class FactoryDynamicURLClassLoader extends DynamicURLClassLoader {
+
+ /**
+ * @param parent is the parent class loader.
+ * @param acc is the accessible context.
+ * @param urls is the list of urls to insert inside the class loading path.
+ */
+ protected FactoryDynamicURLClassLoader(ClassLoader parent, AccessControlContext acc, URL... urls) {
+ super(parent,acc,urls);
+ }
+
+ /** {@inheritDoc}
+ *
+ * @param name {@inheritDoc}
+ * @param resolve {@inheritDoc}
+ * @return {@inheritDoc}
+ * @throws ClassNotFoundException {@inheritDoc}
+ */
+ @Override
+ public final synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ // First check if we have permission to access the package. This
+ // should go away once we've added support for exported packages.
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ int i = name.lastIndexOf('.');
+ if (i != -1) {
+ sm.checkPackageAccess(name.substring(0, i));
+ }
+ }
+ return super.loadClass(name, resolve);
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLStreamHandlerFactory.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLStreamHandlerFactory.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/DynamicURLStreamHandlerFactory.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,130 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * This class defines a factory for <code>URL</code> stream protocol handlers
+ * which is generic and extendable.
+ * <p>
+ * It is used by the <code>URL</code> class to create a
+ * <code>URLStreamHandler</code> for protocols.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new GenericURLStreamHandlerFactory());</code>.
+ * <p>
+ * By default this factory known the following protocols:
+ * <ul>
+ * <li><code>file</code>: {@link FileURLStreamHandler}</li>
+ * <li><code>resource</code>: {@link ResourceURLStreamHandler}</li>
+ * </ul>
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandlerFactory
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ */
+public class DynamicURLStreamHandlerFactory
+implements URLStreamHandlerFactory {
+
+ private final Map<String, Class<? extends URLStreamHandler>> handlers
+ = new TreeMap<String, Class<? extends URLStreamHandler>>();
+
+ /**
+ * Create an URLStreamHandler factory with default protocols.
+ */
+ public DynamicURLStreamHandlerFactory() {
+ addHandler("file", FileURLStreamHandler.class); //$NON-NLS-1$
+ addHandler("resource", ResourceURLStreamHandler.class); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ Class<? extends URLStreamHandler> handler = this.handlers.get(protocol.toLowerCase());
+ if (handler!=null) {
+ try {
+ return handler.newInstance();
+ }
+ catch (Throwable _) {
+ // Ignore errors.
+ }
+ }
+ // Force the default factory to retreive stream handler.
+ return null;
+ }
+
+ /** Add an handler for the given protocol.
+ *
+ * @param protocol is the protocol to register.
+ * @param handler is the type of handler to instance when treating an URL with given protocol.
+ * @return the handler previously binded to the given protocol, or <code>null</code>.
+ */
+ public Class<? extends URLStreamHandler> addHandler(String protocol, Class<? extends URLStreamHandler> handler) {
+ return this.handlers.put(protocol.toLowerCase(), handler);
+ }
+
+ /** Remove handler for the given protocol.
+ *
+ * @param protocol is the protocol to remove.
+ * @return the handler previously binded to the given protocol, or <code>null</code>.
+ */
+ public Class<? extends URLStreamHandler> removeHandler(String protocol) {
+ return this.handlers.remove(protocol.toLowerCase());
+ }
+
+ /** Replies handler for the given protocol.
+ *
+ * @param protocol is the protocol to search for.
+ * @return the handler binded to the given protocol, or <code>null</code>.
+ */
+ public Class<? extends URLStreamHandler> getHandler(String protocol) {
+ return this.handlers.get(protocol.toLowerCase());
+ }
+
+ /** Replies if the given protocol is supported.
+ *
+ * @param protocol is the protocol.
+ * @return <code>true</code> if the given protocol is known, otherwise
+ * <code>false</code>
+ */
+ public boolean contains(String protocol) {
+ return this.handlers.containsKey(protocol.toLowerCase());
+ }
+
+ /** Replies an unmodifiable set of the known protocols.
+ *
+ * @return the known protocols
+ */
+ public Set<String> getProtocols() {
+ return Collections.unmodifiableSet(this.handlers.keySet());
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.URL;
+
+/**
+ * Indicates that the object implementing this interface
+ * owns a external resource.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public interface ExternalizableResource {
+
+ /** Replies the URL where the resource data could be find.
+ *
+ * @return the URL to the external resource.
+ */
+ public URL getExternalizableResourceLocation();
+
+ /** Replies the MIME type of the external resource.
+ *
+ * @return the MIME of the external resource.
+ */
+ public String getExternalizableResourceType();
+
+}
\ No newline at end of file
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileSystem.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileSystem.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileSystem.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,1508 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+
+
+/** An utility class that permits to deal with filenames.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class FileSystem {
+
+ /** Character used to specify a file extension.
+ */
+ public static final char EXTENSION_SEPARATOR_CHAR = '.';
+
+ /** String which is representing the current directory in a relative path.
+ */
+ public static final String CURRENT_DIRECTORY = "."; //$NON-NLS-1$
+
+ /** String which is representing the parent directory in a relative path.
+ */
+ public static final String PARENT_DIRECTORY = ".."; //$NON-NLS-1$
+
+ /** Character used to separate paths on an URL.
+ */
+ public static final char URL_PATH_SEPARATOR_CHAR = '/';
+
+ /** Character used to separate paths on an URL.
+ */
+ public static final String URL_PATH_SEPARATOR = "/"; //$NON-NLS-1$
+
+ /** String used to specify a file extension.
+ */
+ public static final String EXTENSION_SEPARATOR = "."; //$NON-NLS-1$
+
+ /** Prefix used to join in a Jar URL the jar filename and the inside-jar filename.
+ */
+ public static final String JAR_URL_FILE_ROOT = "!/"; //$NON-NLS-1$
+
+ /** Replies if the given URL has a jar scheme.
+ *
+ * @param url
+ * @return <code>true</code> if the given URL uses a jar scheme.
+ */
+ public static boolean isJarURL(URL url) {
+ return url!=null && "jar".equalsIgnoreCase(url.getProtocol()); //$NON-NLS-1$
+ }
+
+ /** Replies the jar part of the jar-scheme URL.
+ *
+ * @param url
+ * @return the URL of the jar file in the given URL, or <code>null</code>
+ * if the given URL does not use jar scheme.
+ */
+ public static URL getJarURL(URL url) {
+ if (!isJarURL(url)) return null;
+ String path = url.getPath();
+ int idx = path.lastIndexOf(JAR_URL_FILE_ROOT);
+ if (idx>=0) path = path.substring(0, idx);
+ try {
+ return new URL(path);
+ }
+ catch(MalformedURLException _) {
+ return null;
+ }
+ }
+
+ /** Replies the file part of the jar-scheme URL.
+ *
+ * @param url
+ * @return the file in the given URL, or <code>null</code>
+ * if the given URL does not use jar scheme.
+ */
+ public static File getJarFile(URL url) {
+ if (isJarURL(url)) {
+ String path = url.getPath();
+ int idx = path.lastIndexOf(JAR_URL_FILE_ROOT);
+ if (idx>=0) return new File(path.substring(idx+1));
+ }
+ return null;
+ }
+
+ /** Replies the jar-schemed URL composed of the two given components.
+ *
+ * @param jarFile is the URL to the jar file.
+ * @param insideFile is the name of the file inside the jar.
+ * @return the jar-schemed URL.
+ * @throws MalformedURLException when the URL is malformed.
+ */
+ public static URL toJarURL(File jarFile, File insideFile) throws MalformedURLException {
+ if (jarFile==null || insideFile==null) return null;
+ return toJarURL(jarFile, insideFile.getPath());
+ }
+
+ /** Replies the jar-schemed URL composed of the two given components.
+ *
+ * @param jarFile is the URL to the jar file.
+ * @param insideFile is the name of the file inside the jar.
+ * @return the jar-schemed URL.
+ * @throws MalformedURLException when the URL is malformed.
+ */
+ public static URL toJarURL(File jarFile, String insideFile) throws MalformedURLException {
+ if (jarFile==null || insideFile==null) return null;
+ StringBuffer buf = new StringBuffer("jar:"); //$NON-NLS-1$
+ buf.append(jarFile.toURI().toURL().toExternalForm());
+ buf.append(JAR_URL_FILE_ROOT);
+ String path = insideFile.replace(File.separatorChar, URL_PATH_SEPARATOR_CHAR);
+ if (path.startsWith(URL_PATH_SEPARATOR)) {
+ buf.append(path.substring(URL_PATH_SEPARATOR.length()));
+ }
+ else {
+ buf.append(path);
+ }
+ return new URL(buf.toString());
+ }
+
+ /** Replies the jar-schemed URL composed of the two given components.
+ *
+ * @param jarFile is the URL to the jar file.
+ * @param insideFile is the name of the file inside the jar.
+ * @return the jar-schemed URL.
+ * @throws MalformedURLException when the URL is malformed.
+ */
+ public static URL toJarURL(URL jarFile, File insideFile) throws MalformedURLException {
+ if (jarFile==null || insideFile==null) return null;
+ return toJarURL(jarFile, insideFile.getPath());
+ }
+
+ /** Replies the jar-schemed URL composed of the two given components.
+ *
+ * @param jarFile is the URL to the jar file.
+ * @param insideFile is the name of the file inside the jar.
+ * @return the jar-schemed URL.
+ * @throws MalformedURLException when the URL is malformed.
+ */
+ public static URL toJarURL(URL jarFile, String insideFile) throws MalformedURLException {
+ if (jarFile==null || insideFile==null) return null;
+ StringBuffer buf = new StringBuffer("jar:"); //$NON-NLS-1$
+ buf.append(jarFile.toExternalForm());
+ buf.append(JAR_URL_FILE_ROOT);
+ String path = insideFile.replace(File.separatorChar, URL_PATH_SEPARATOR_CHAR);
+ if (path.startsWith(URL_PATH_SEPARATOR)) {
+ buf.append(path.substring(URL_PATH_SEPARATOR.length()));
+ }
+ else {
+ buf.append(path);
+ }
+ return new URL(buf.toString());
+ }
+
+ /** Replies if the current operating system uses case-sensitive filename.
+ *
+ * @return <code>true</code> if the filenames on the current file system are case sensitive,
+ * otherwise <code>false</code>
+ */
+ public static boolean isCaseSensitiveFilenameSystem() {
+ switch(OperatingSystem.getCurrentOS()) {
+ case AIX:
+ case BSD:
+ case FREEBSD:
+ case NETBSD:
+ case OPENBSD:
+ case LINUX:
+ case SOLARIS:
+ case HPUX:
+ return true;
+ case MACOSX:
+ case WIN:
+ case OTHER:
+ default:
+ return false;
+ }
+ }
+
+ /** Replies the character used to separate the basename and the file extension.
+ *
+ * @return the character used to separate the basename and the file extension.
+ */
+ public static char getFileExtensionCharacter() {
+ return EXTENSION_SEPARATOR_CHAR;
+ }
+
+ /** Replies the dirname of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the dirname of the specified file.
+ * @see #shortBasename(String)
+ * @see #largeBasename(String)
+ * @see #basename(String)
+ * @see #extension(String)
+ * @deprecated use {@link #extension(File)} or {@link #extension(URL)}
+ */
+ @Deprecated
+ public static String dirname(String filename) {
+ if (filename==null) return null;
+ int idx = filename.lastIndexOf(File.separatorChar);
+ if (idx<0) return CURRENT_DIRECTORY;
+ if (idx==0) return File.separator;
+ return filename.substring(0,idx);
+ }
+
+ /** Replies the dirname of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the dirname of the specified file.
+ * @see #shortBasename(File)
+ * @see #largeBasename(File)
+ * @see #basename(File)
+ * @see #extension(File)
+ */
+ public static File dirname(File filename) {
+ if (filename==null) return null;
+ return filename.getParentFile();
+ }
+
+ /** Replies the dirname of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the dirname of the specified file.
+ * @see #shortBasename(URL)
+ * @see #largeBasename(URL)
+ * @see #basename(URL)
+ * @see #extension(URL)
+ */
+ public static URL dirname(URL filename) {
+ if (filename==null) return null;
+
+ URL prefix = null;
+ String path;
+ if (isJarURL(filename)) {
+ prefix = getJarURL(filename);
+ path = getJarFile(filename).getPath();
+ }
+ else
+ path = filename.getPath();
+
+ int idx = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+ if (idx==path.length()-1)
+ idx = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR, path.length()-2);
+
+ path = (idx<0) ? URL_PATH_SEPARATOR : path.substring(0, idx+1);
+
+ try {
+ if (prefix!=null) {
+ return toJarURL(prefix, path);
+ }
+ URI uri = new URI(
+ filename.getProtocol(),
+ filename.getUserInfo(),
+ filename.getHost(),
+ filename.getPort(),
+ path,
+ null,
+ null);
+ return uri.toURL();
+ }
+ catch (Throwable _) {
+ return null;
+ }
+ }
+
+ /** Replies the basename of the specified file with the extension.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file with the extension.
+ */
+ public static String largeBasename(String filename) {
+ if (filename==null) return null;
+ int idx = filename.lastIndexOf(File.separatorChar);
+ return (idx<0) ? filename : filename.substring(idx+1);
+ }
+
+ /** Replies the basename of the specified file with the extension.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file with the extension.
+ */
+ public static String largeBasename(File filename) {
+ if (filename==null) return null;
+ return filename.getName();
+ }
+
+ /** Replies the basename of the specified file with the extension.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file with the extension.
+ */
+ public static String largeBasename(URL filename) {
+ if (filename==null) return null;
+ String fullPath = filename.getPath();
+ int idx = fullPath.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+ int end = fullPath.length();
+ if (idx==end-1) {
+ end --;
+ idx = fullPath.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end-1);
+ }
+ if (idx<0) idx = -1;
+ return fullPath.substring(idx+1, end);
+ }
+
+ /** Reply the basename of the specified file without the last extension.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file without the last extension.
+ * @see #shortBasename(String)
+ * @see #largeBasename(String)
+ * @see #dirname(String)
+ * @see #extension(String)
+ */
+ public static String basename(String filename) {
+ if (filename==null) return null;
+ int idx = filename.lastIndexOf(File.separatorChar);
+ String basename = (idx<0) ? filename : filename.substring(idx+1);
+ idx = basename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<0) return basename;
+ return basename.substring(0,idx);
+ }
+
+ /** Reply the basename of the specified file without the last extension.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file without the last extension.
+ * @see #shortBasename(File)
+ * @see #largeBasename(File)
+ * @see #dirname(File)
+ * @see #extension(File)
+ */
+ public static String basename(File filename) {
+ if (filename==null) return null;
+ String largeBasename = filename.getName();
+ int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<=0) return largeBasename;
+ return largeBasename.substring(0,idx);
+ }
+
+ /** Reply the basename of the specified file without the last extension.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file without the last extension.
+ * @see #shortBasename(URL)
+ * @see #largeBasename(URL)
+ * @see #dirname(URL)
+ * @see #extension(URL)
+ */
+ public static String basename(URL filename) {
+ if (filename==null) return null;
+ String largeBasename = filename.getPath();
+ int idx = largeBasename.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+ int end = largeBasename.length();
+ if (idx==end-1) {
+ end --;
+ idx = largeBasename.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end-1);
+ }
+ if (idx<0) idx = -1;
+ largeBasename = largeBasename.substring(idx+1, end);
+ idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<0) return largeBasename;
+ return largeBasename.substring(0,idx);
+ }
+
+ /** Reply the basename of the specified file without all the extensions.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file without all the extensions.
+ */
+ public static String shortBasename(String filename) {
+ if (filename==null) return null;
+ int idx = filename.lastIndexOf(File.separatorChar);
+ String basename = (idx<0) ? filename : filename.substring(idx+1);
+ idx = basename.indexOf(getFileExtensionCharacter());
+ if (idx<0) return basename;
+ return basename.substring(0,idx);
+ }
+
+ /** Reply the basename of the specified file without all the extensions.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file without all the extensions.
+ */
+ public static String shortBasename(File filename) {
+ if (filename==null) return null;
+ String largeBasename = filename.getName();
+ int idx = largeBasename.indexOf(getFileExtensionCharacter());
+ if (idx<0) return largeBasename;
+ return largeBasename.substring(0,idx);
+ }
+
+ /** Reply the basename of the specified file without all the extensions.
+ *
+ * @param filename is the name to parse.
+ * @return the basename of the specified file without all the extensions.
+ */
+ public static String shortBasename(URL filename) {
+ if (filename==null) return null;
+ String largeBasename = filename.getPath();
+ int idx = largeBasename.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+ int end = largeBasename.length();
+ if (idx==end-1) {
+ end --;
+ idx = largeBasename.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end-1);
+ }
+ if (idx<0) idx = -1;
+ largeBasename = largeBasename.substring(idx+1, end);
+ idx = largeBasename.indexOf(getFileExtensionCharacter());
+ if (idx<0) return largeBasename;
+ return largeBasename.substring(0,idx);
+ }
+
+ /** Reply the extension of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the extension of the specified file
+ * @deprecated use {@link #extension(File)} or {@link #extension(URL)}
+ * @see #shortBasename(String)
+ * @see #largeBasename(String)
+ * @see #basename(String)
+ * @see #dirname(String)
+ * @see #extensions(String)
+ */
+ @Deprecated
+ public static String extension(String filename) {
+ try {
+ return extension(new URL(filename));
+ }
+ catch(MalformedURLException _) {
+ return extension(new File(filename));
+ }
+ }
+
+ /** Reply the extension of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the extension of the specified file
+ * @see #shortBasename(File)
+ * @see #largeBasename(File)
+ * @see #basename(File)
+ * @see #dirname(File)
+ * @see #extensions(File)
+ */
+ public static String extension(File filename) {
+ if (filename==null) return null;
+ String largeBasename = largeBasename(filename);
+ int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<=0) return ""; //$NON-NLS-1$
+ return largeBasename.substring(idx);
+ }
+
+ /** Reply the extension of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the extension of the specified file
+ * @see #shortBasename(URL)
+ * @see #largeBasename(URL)
+ * @see #basename(URL)
+ * @see #dirname(URL)
+ * @see #extensions(URL)
+ */
+ public static String extension(URL filename) {
+ if (filename==null) return null;
+ String largeBasename = largeBasename(filename);
+ int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<=0) return ""; //$NON-NLS-1$
+ return largeBasename.substring(idx);
+ }
+
+ /** Reply all the extensions of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the extensions of the specified file
+ * @deprecated use {@link #extensions(File)} or {@link #extensions(URL)}
+ */
+ @Deprecated
+ public static String[] extensions(String filename) {
+ try {
+ return extensions(new URL(filename));
+ }
+ catch(MalformedURLException _) {
+ return extensions(new File(filename));
+ }
+ }
+
+ /** Reply all the extensions of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the extensions of the specified file
+ */
+ public static String[] extensions(File filename) {
+ if (filename==null) return new String[0];
+ String largeBasename = largeBasename(filename);
+ String[] parts = largeBasename.split("["+getFileExtensionCharacter()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (parts.length<=1) return new String[0];
+ String[] r = new String[parts.length-1];
+ System.arraycopy(parts, 1, r, 0, r.length);
+ return r;
+ }
+
+ /** Reply all the extensions of the specified file.
+ *
+ * @param filename is the name to parse.
+ * @return the extensions of the specified file
+ */
+ public static String[] extensions(URL filename) {
+ if (filename==null) return new String[0];
+ String largeBasename = largeBasename(filename);
+ String[] parts = largeBasename.split("["+getFileExtensionCharacter()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (parts.length<=1) return new String[0];
+ String[] r = new String[parts.length-1];
+ System.arraycopy(parts, 1, r, 0, r.length);
+ return r;
+ }
+
+ /** Replies the parts of a path.
+ *
+ * @param filename is the name to parse.
+ * @return the parts of a path.
+ * @deprecated use {@link #split(File)} or {@link #split(URL)}
+ */
+ @Deprecated
+ public static String[] split(String filename) {
+ try {
+ return split(new URL(filename));
+ }
+ catch(MalformedURLException _) {
+ return split(new File(filename));
+ }
+ }
+
+ /** Replies the parts of a path.
+ *
+ * @param filename is the name to parse.
+ * @return the parts of a path.
+ */
+ public static String[] split(File filename) {
+ if (filename==null) return new String[0];
+ return filename.getPath().split("["+File.separatorChar+"]"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /** Replies the parts of a path.
+ *
+ * @param filename is the name to parse.
+ * @return the parts of a path.
+ */
+ public static String[] split(URL filename) {
+ if (filename==null) return new String[0];
+ String path;
+ if (isJarURL(filename))
+ path = getJarFile(filename).getPath();
+ else
+ path = filename.getPath();
+ return path.split("["+URL_PATH_SEPARATOR_CHAR+"]"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /** Join the parts of a path with the current OS directory separator.
+ *
+ * @param elements are the path's elements to join.
+ * @return the result of the join of the path's elements.
+ * @deprecated use {@link #split(File)} or {@link #split(URL)}
+ */
+ @Deprecated
+ public static String join(String... elements) {
+ StringBuffer buf = new StringBuffer();
+ boolean first = true;
+ boolean empty;
+ for(String elt : elements) {
+ empty = (elt==null || elt.length()==0);
+ if (first && empty) {
+ buf.append(File.separatorChar);
+ }
+ else if (!empty) {
+ if (buf.length()>0 && buf.charAt(buf.length()-1)!=File.separatorChar)
+ buf.append(File.separatorChar);
+ buf.append(elt);
+ }
+ first = false;
+ }
+ return buf.toString();
+ }
+
+ /** Join the parts of a path and append them to the given File.
+ *
+ * @param fileBase is the file to put as prefix.
+ * @param elements are the path's elements to join.
+ * @return the result of the join of the path's elements.
+ */
+ public static File join(File fileBase, String... elements) {
+ if (fileBase==null) return null;
+ StringBuffer buf = new StringBuffer(fileBase.getPath());
+ boolean empty;
+ for(String elt : elements) {
+ empty = (elt==null || elt.length()==0);
+ if (!empty) {
+ assert(elt!=null);
+ if (!elt.startsWith(File.separator)
+ && buf.length()>=0
+ && buf.charAt(buf.length()-1)!=File.separatorChar) {
+ buf.append(File.separatorChar);
+ }
+ buf.append(elt);
+ }
+ }
+ return new File(buf.toString());
+ }
+
+ /** Join the parts of a path and append them to the given File.
+ *
+ * @param fileBase is the file to put as prefix.
+ * @param elements are the path's elements to join.
+ * @return the result of the join of the path's elements.
+ */
+ public static File join(File fileBase, File... elements) {
+ if (fileBase==null) return null;
+ StringBuffer buf = new StringBuffer(fileBase.getPath());
+ for(File elt : elements) {
+ if (!elt.isAbsolute()) {
+ if (buf.length()>=0 && buf.charAt(buf.length()-1)!=File.separatorChar) {
+ buf.append(File.separatorChar);
+ }
+ }
+ buf.append(elt.getPath());
+ }
+ return new File(buf.toString());
+ }
+
+ /** Join the parts of a path and append them to the given URL.
+ *
+ * @param urlBase is the url to put as prefix.
+ * @param elements are the path's elements to join.
+ * @return the result of the join of the path's elements.
+ */
+ public static URL join(URL urlBase, String... elements) {
+ if (urlBase==null) return null;
+ StringBuffer buf = new StringBuffer(urlBase.getPath());
+ boolean empty;
+ for(String elt : elements) {
+ empty = (elt==null || elt.length()==0);
+ if (!empty) {
+ assert(elt!=null);
+ if (!elt.startsWith(File.separator)
+ && (buf.length()==0
+ || buf.charAt(buf.length()-1)!=URL_PATH_SEPARATOR_CHAR)) {
+ buf.append(URL_PATH_SEPARATOR_CHAR);
+ }
+ buf.append(elt);
+ }
+ }
+ try {
+ if (isJarURL(urlBase)) {
+ return new URL(
+ urlBase.getProtocol(),
+ urlBase.getHost(),
+ urlBase.getPort(),
+ buf.toString());
+ }
+ URI uri = new URI(
+ urlBase.getProtocol(),
+ urlBase.getUserInfo(),
+ urlBase.getHost(),
+ urlBase.getPort(),
+ buf.toString(),
+ urlBase.getQuery(),
+ urlBase.getRef());
+ return uri.toURL();
+ }
+ catch (Throwable _) {
+ return null;
+ }
+ }
+
+ /** Join the parts of a path and append them to the given URL.
+ *
+ * @param urlBase is the url to put as prefix.
+ * @param elements are the path's elements to join.
+ * @return the result of the join of the path's elements.
+ */
+ public static URL join(URL urlBase, File... elements) {
+ if (urlBase==null) return null;
+ StringBuffer buf = new StringBuffer(urlBase.getPath());
+ for(File elt : elements) {
+ if (!elt.isAbsolute()) {
+ if (buf.length()==0 || buf.charAt(buf.length()-1)!=URL_PATH_SEPARATOR_CHAR) {
+ buf.append(URL_PATH_SEPARATOR_CHAR);
+ }
+ }
+ buf.append(elt.getPath());
+ }
+ try {
+ if (isJarURL(urlBase)) {
+ return new URL(
+ urlBase.getProtocol(),
+ urlBase.getHost(),
+ urlBase.getPort(),
+ buf.toString());
+ }
+ URI uri = new URI(
+ urlBase.getProtocol(),
+ urlBase.getUserInfo(),
+ urlBase.getHost(),
+ urlBase.getPort(),
+ buf.toString(),
+ urlBase.getQuery(),
+ urlBase.getRef());
+ return uri.toURL();
+ }
+ catch (Throwable _) {
+ return null;
+ }
+ }
+
+ /** Replies if the specified file has the specified extension.
+ * <p>
+ * The test is dependent of the case-sensitive attribute of operating system.
+ *
+ * @param filename is the filename to parse
+ * @param extension is the extension to test.
+ * @return <code>true</code> if the given filename has the given extension,
+ * otherwise <code>false</code>
+ * @deprecated use {@link #hasExtension(File,String)} or {@link #hasExtension(URL,String)}
+ */
+ @Deprecated
+ public static boolean hasExtension(String filename, String extension) {
+ try {
+ return hasExtension(new URL(filename), extension);
+ }
+ catch(MalformedURLException _) {
+ return hasExtension(new File(filename), extension);
+ }
+ }
+
+ /** Replies if the specified file has the specified extension.
+ * <p>
+ * The test is dependent of the case-sensitive attribute of operating system.
+ *
+ * @param filename is the filename to parse
+ * @param extension is the extension to test.
+ * @return <code>true</code> if the given filename has the given extension,
+ * otherwise <code>false</code>
+ */
+ public static boolean hasExtension(File filename, String extension) {
+ if (filename==null) return false;
+ String extent = extension;
+ if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+ extent = EXTENSION_SEPARATOR+extent;
+ String ext = extension(filename);
+ if (ext==null) return false;
+ if (isCaseSensitiveFilenameSystem())
+ return ext.equals(extent);
+ return ext.equalsIgnoreCase(extent);
+ }
+
+ /** Replies if the specified file has the specified extension.
+ * <p>
+ * The test is dependent of the case-sensitive attribute of operating system.
+ *
+ * @param filename is the filename to parse
+ * @param extension is the extension to test.
+ * @return <code>true</code> if the given filename has the given extension,
+ * otherwise <code>false</code>
+ */
+ public static boolean hasExtension(URL filename, String extension) {
+ if (filename==null) return false;
+ String extent = extension;
+ if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+ extent = EXTENSION_SEPARATOR+extent;
+ String ext = extension(filename);
+ if (ext==null) return false;
+ if (isCaseSensitiveFilenameSystem())
+ return ext.equals(extent);
+ return ext.equalsIgnoreCase(extent);
+ }
+
+ /** Remove the extension from the specified filename.
+ *
+ * @param filename is the filename to parse.
+ * @return the filename without the extension.
+ * @deprecated use {@link #removeExtension(File)} or {@link #removeExtension(URL)}
+ */
+ @Deprecated
+ public static String removeExtension(String filename) {
+ try {
+ return removeExtension(new URL(filename)).toExternalForm();
+ }
+ catch(MalformedURLException _) {
+ return removeExtension(new File(filename)).getPath();
+ }
+ }
+
+ /** Remove the extension from the specified filename.
+ *
+ * @param filename is the filename to parse.
+ * @return the filename without the extension.
+ */
+ public static File removeExtension(File filename) {
+ if (filename==null) return null;
+ File dir = filename.getParentFile();
+ String name = filename.getName();
+ int idx = name.lastIndexOf(getFileExtensionCharacter());
+ if (idx<0) return filename;
+ return new File(dir, name.substring(0,idx));
+ }
+
+ /** Remove the extension from the specified filename.
+ *
+ * @param filename is the filename to parse.
+ * @return the filename without the extension.
+ */
+ public static URL removeExtension(URL filename) {
+ if (filename==null) return null;
+ String path = filename.getPath();
+ int idx = path.lastIndexOf(URL_PATH_SEPARATOR);
+ StringBuffer buf = new StringBuffer((idx<0) ? "" : path.substring(0, idx+1)); //$NON-NLS-1$
+ String largeBasename = path.substring(idx+1);
+ idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<0) return filename;
+ buf.append(largeBasename.substring(0, idx));
+ try {
+ if (isJarURL(filename)) {
+ return new URL(
+ filename.getProtocol(),
+ filename.getHost(),
+ filename.getPort(),
+ buf.toString());
+ }
+ URI uri = new URI(
+ filename.getProtocol(),
+ filename.getUserInfo(),
+ filename.getHost(),
+ filename.getPort(),
+ buf.toString(),
+ filename.getQuery(),
+ filename.getRef());
+ return uri.toURL();
+ }
+ catch(Throwable _) {
+ return null;
+ }
+ }
+
+ /** Replace the extension of the specified filename by the given extension.
+ * If the filename has no extension, the specifiedone will be added.
+ *
+ * @param filename is the filename to parse.
+ * @param extension is the extension to remove if it is existing.
+ * @return the filename without the extension.
+ * @deprecated use {@link #replaceExtension(File,String)} or {@link #replaceExtension(URL,String)}
+ */
+ @Deprecated
+ public static String replaceExtension(String filename, String extension) {
+ try {
+ return replaceExtension(new URL(filename), extension).toExternalForm();
+ }
+ catch(MalformedURLException _) {
+ return replaceExtension(new File(filename), extension).getPath();
+ }
+ }
+
+ /** Replace the extension of the specified filename by the given extension.
+ * If the filename has no extension, the specified one will be added.
+ *
+ * @param filename is the filename to parse.
+ * @param extension is the extension to remove if it is existing.
+ * @return the filename without the extension.
+ */
+ public static File replaceExtension(File filename, String extension) {
+ if (filename==null) return null;
+ File dir = filename.getParentFile();
+ String name = filename.getName();
+ int idx = name.lastIndexOf(getFileExtensionCharacter());
+ if (idx<0) return new File(dir, name+extension);
+ return new File(dir, name.substring(0,idx)+extension);
+ }
+
+ /** Replace the extension of the specified filename by the given extension.
+ * If the filename has no extension, the specified one will be added.
+ *
+ * @param filename is the filename to parse.
+ * @param extension is the extension to remove if it is existing.
+ * @return the filename without the extension.
+ */
+ public static URL replaceExtension(URL filename, String extension) {
+ if (filename==null) return null;
+ String path = filename.getPath();
+ int idx = path.lastIndexOf(URL_PATH_SEPARATOR);
+ int end = path.length();
+ if (idx==end-1) {
+ end --;
+ idx = path.lastIndexOf(URL_PATH_SEPARATOR, end-1);
+ }
+ StringBuffer buf = new StringBuffer((idx<0) ? "" : path.substring(0, idx+1)); //$NON-NLS-1$
+ String largeBasename = path.substring(idx+1, end);
+ idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+ if (idx<0) {
+ buf.append(largeBasename);
+ }
+ else {
+ buf.append(largeBasename.substring(0, idx));
+ }
+ buf.append(extension);
+ try {
+ if (isJarURL(filename)) {
+ return new URL(
+ filename.getProtocol(),
+ filename.getHost(),
+ filename.getPort(),
+ buf.toString());
+ }
+ URI uri = new URI(
+ filename.getProtocol(),
+ filename.getUserInfo(),
+ filename.getHost(),
+ filename.getPort(),
+ buf.toString(),
+ filename.getQuery(),
+ filename.getRef());
+ return uri.toURL();
+ }
+ catch(Throwable _) {
+ return null;
+ }
+ }
+
+ /** Copy the first file into the second file.
+ * <p>
+ * The content of the second file will be lost.
+ * This copy function allows to do a copy between two different
+ * partitions.
+ *
+ * @param in is the file to copy.
+ * @param out is the target file
+ * @throws IOException in case of error.
+ * @see #fileCopy(URL, File)
+ */
+ public static void fileCopy(File in, File out) throws IOException {
+ FileChannel inChannel = new FileInputStream(in).getChannel();
+ FileChannel outChannel = new FileOutputStream(out).getChannel();
+ try {
+ // apparently has trouble copying large files on Windows
+ if (OperatingSystem.WIN.isCurrentOS()) {
+ // magic number for Windows, 64Mb - 32Kb
+ int maxCount = (64 * 1024 * 1024) - (32 * 1024);
+ long size = inChannel.size();
+ long position = 0;
+ while ( position < size ) {
+ position += inChannel.transferTo( position, maxCount, outChannel );
+ }
+ }
+ else {
+ inChannel.transferTo(0, inChannel.size(), outChannel);
+ }
+ }
+ finally {
+ if (inChannel!=null) inChannel.close();
+ if (outChannel!=null) outChannel.close();
+ }
+ }
+
+ /** Copy the first file into the second file.
+ * <p>
+ * The content of the second file will be lost.
+ * This copy function allows to do a copy between two different
+ * partitions.
+ *
+ * @param in is the file to copy.
+ * @param out is the target file
+ * @throws IOException in case of error.
+ * @see #fileCopy(File, File)
+ */
+ public static void fileCopy(URL in, File out) throws IOException {
+ URLConnection connection = in.openConnection();
+ ReadableByteChannel inChannel = Channels.newChannel(connection.getInputStream());
+ FileChannel outChannel = new FileOutputStream(out).getChannel();
+ int size = connection.getContentLength();
+ try {
+ // apparently has trouble copying large files on Windows
+ if (size<0 || OperatingSystem.WIN.isCurrentOS()) {
+ // magic number for Windows, 64Mb - 32Kb
+ int maxCount = (64 * 1024 * 1024) - (32 * 1024);
+ long position = 0;
+ long copied = 1;
+ while ( (size>=0 && position<size) || (size<0 && copied>0)) {
+ copied = outChannel.transferFrom(inChannel, position, maxCount);
+ position += copied;
+ }
+ }
+ else {
+ outChannel.transferFrom(inChannel, 0, size);
+ }
+ }
+ finally {
+ if (inChannel!=null) inChannel.close();
+ if (outChannel!=null) outChannel.close();
+ }
+ }
+
+ /** Replies the user home directory.
+ *
+ * @return the home directory of the current user.
+ * @throws FileNotFoundException
+ */
+ public static File getUserHomeDirectory() throws FileNotFoundException {
+ String userHome = System.getProperty("user.home"); //$NON-NLS-1$
+ if (userHome!=null) {
+ File file = new File(userHome);
+ if (file.isDirectory()) return file;
+ }
+ throw new FileNotFoundException();
+ }
+
+ /** Replies the user home directory.
+ *
+ * @return the home directory of the current user.
+ */
+ public static String getUserHomeDirectoryName() {
+ return System.getProperty("user.home"); //$NON-NLS-1$
+ }
+
+ /** Replies the user configuration directory for the specified software.
+ * <p>
+ * On Unix operating systems, the user directory for a
+ * software is by default {@code $HOME/.software} where {@code software}
+ * is the given parameter (case-sensitive). On Windows® operating systems, the user
+ * directory for a software is by default
+ * {@code C:<span>\</span>Documents and Settings<span>\</span>userName<span>\</span>Local Settings<span>\</span>Application Data<span>\</span>software}
+ * where {@code userName} is the login of the current user and {@code software}
+ * is the given parameter (case-insensitive).
+ *
+ * @param software is the name of the concerned software.
+ * @return the configuration directory of the software for the current user.
+ */
+ public static File getUserConfigurationDirectoryFor(String software) {
+ try {
+ File userHome = getUserHomeDirectory();
+ OperatingSystem os = OperatingSystem.getCurrentOS();
+ if (os.isUnixCompliant()) {
+ return new File(userHome, "."+software); //$NON-NLS-1$
+ }
+ else if (os==OperatingSystem.WIN) {
+ String userName = System.getProperty("user.name"); //$NON-NLS-1$
+ if (userName!=null && !"".equals(userName)) { //$NON-NLS-1$
+ return join(
+ new File("C:"), //$NON-NLS-1$
+ "Documents and Settings", //$NON-NLS-1$
+ userName,
+ "Local Settings","Application Data", //$NON-NLS-1$//$NON-NLS-2$
+ software);
+ }
+ }
+ return new File(userHome,software);
+ }
+ catch(FileNotFoundException _) {
+ //
+ }
+ return null;
+ }
+
+ /** Replies the user configuration directory for the specified software.
+ * <p>
+ * On Unix operating systems, the user directory for a
+ * software is by default {@code $HOME/.software} where {@code software}
+ * is the given parameter (case-sensitive). On Windows® operating systems, the user
+ * directory for a software is by default
+ * {@code C:<span>\</span>Documents and Settings<span>\</span>userName<span>\</span>Local Settings<span>\</span>Application Data<span>\</span>software}
+ * where {@code userName} is the login of the current user and {@code software}
+ * is the given parameter (case-insensitive).
+ *
+ * @param software is the name of the concerned software.
+ * @return the configuration directory of the software for the current user.
+ */
+ public static String getUserConfigurationDirectoryNameFor(String software) {
+ File directory = getUserConfigurationDirectoryFor(software);
+ if (directory!=null) return directory.getAbsolutePath();
+ return null;
+ }
+
+ /** Replies the system configuration directory for the specified software.
+ * <p>
+ * On Unix operating systems, the system directory for a
+ * software is by default {@code /etc/software} where {@code software}
+ * is the given parameter (case-sensitive). On Windows® operating systems, the user
+ * directory for a software is by default
+ * {@code C:<span>\</span>Program Files<span>\</span>software}
+ * where {@code software} is the given parameter (case-insensitive).
+ *
+ * @param software is the name of the concerned software.
+ * @return the configuration directory of the software for the current user.
+ */
+ public static File getSystemConfigurationDirectoryFor(String software) {
+ OperatingSystem os = OperatingSystem.getCurrentOS();
+ if (os.isUnixCompliant()) {
+ File[] roots = File.listRoots();
+ return join(roots[0],"etc", software); //$NON-NLS-1$
+ }
+ else if (os==OperatingSystem.WIN) {
+ File pfDirectory;
+ for(File root : File.listRoots()) {
+ pfDirectory = new File(root, "Program Files"); //$NON-NLS-1$
+ if (pfDirectory.isDirectory()) {
+ return new File(root, software);
+ }
+ }
+ }
+ return null;
+ }
+
+ /** Replies the user configuration directory for the specified software.
+ * <p>
+ * On Unix operating systems, the system directory for a
+ * software is by default {@code /etc/software} where {@code software}
+ * is the given parameter (case-sensitive). On Windows® operating systems, the user
+ * directory for a software is by default
+ * {@code C:<span>\</span>Program Files<span>\</span>software}
+ * where {@code software} is the given parameter (case-insensitive).
+ *
+ * @param software is the name of the concerned software.
+ * @return the configuration directory of the software for the current user.
+ */
+ public static String getSystemConfigurationDirectoryNameFor(String software) {
+ File directory = getSystemConfigurationDirectoryFor(software);
+ if (directory!=null) return directory.getAbsolutePath();
+ return null;
+ }
+
+ /** Replies the system shared library directory for the specified software.
+ * <p>
+ * On Unix operating systems, the system directory for a
+ * software is by default {@code /usr/lib/software} where {@code software}
+ * is the given parameter (case-sensitive). On Windows® operating systems, the user
+ * directory for a software is by default
+ * {@code C:<span>\</span>Program Files<span>\</span>software}
+ * where {@code software} is the given parameter (case-insensitive).
+ *
+ * @param software is the name of the concerned software.
+ * @return the configuration directory of the software for the current user.
+ */
+ public static File getSystemSharedLibraryDirectoryFor(String software) {
+ OperatingSystem os = OperatingSystem.getCurrentOS();
+ if (os.isUnixCompliant()) {
+ File[] roots = File.listRoots();
+ return join(roots[0],"usr","lib", software); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ else if (os==OperatingSystem.WIN) {
+ File pfDirectory;
+ for(File root : File.listRoots()) {
+ pfDirectory = new File(root, "Program Files"); //$NON-NLS-1$
+ if (pfDirectory.isDirectory()) {
+ return new File(root, software);
+ }
+ }
+ }
+ return null;
+ }
+
+ /** Replies the system shared library directory for the specified software.
+ * <p>
+ * On Unix operating systems, the system directory for a
+ * software is by default {@code /usr/lib/software} where {@code software}
+ * is the given parameter (case-sensitive). On Windows® operating systems, the user
+ * directory for a software is by default
+ * {@code C:<span>\</span>Program Files<span>\</span>software}
+ * where {@code software} is the given parameter (case-insensitive).
+ *
+ * @param software is the name of the concerned software.
+ * @return the configuration directory of the software for the current user.
+ */
+ public static String getSystemSharedLibraryDirectoryNameFor(String software) {
+ File f = getSystemSharedLibraryDirectoryFor(software);
+ if (f==null) return null;
+ return f.getAbsolutePath();
+ }
+
+ /** Convert an URL which represents a local file into a File.
+ *
+ * @param url is the URL to convert.
+ * @return the file.
+ * @throws IllegalArgumentException is the URL was malformed.
+ * @deprecated see {@link #convertUrlToFile(URL)}
+ * @see #convertUrlToFile(URL)
+ */
+ @Deprecated
+ public static File UrlToFile(URL url) {
+ return convertUrlToFile(url);
+ }
+
+ /** Convert an URL which represents a local file into a File.
+ *
+ * @param url is the URL to convert.
+ * @return the file.
+ * @throws IllegalArgumentException is the URL was malformed.
+ */
+ public static File convertUrlToFile(URL url) {
+ URI uri;
+ try {
+ // this is the step that can fail, and so
+ // it should be this step that should be fixed
+ uri = url.toURI();
+ }
+ catch (URISyntaxException e) {
+ // OK if we are here, then obviously the URL did
+ // not comply with RFC 2396. This can only
+ // happen if we have illegal unescaped characters.
+ // If we have one unescaped character, then
+ // the only automated fix we can apply, is to assume
+ // all characters are unescaped.
+ // If we want to construct a URI from unescaped
+ // characters, then we have to use the component
+ // constructors:
+ try {
+ uri = new URI(url.getProtocol(), url.getUserInfo(), url
+ .getHost(), url.getPort(), url.getPath(), url
+ .getQuery(), url.getRef());
+ }
+ catch (URISyntaxException e1) {
+ // The URL is broken beyond automatic repair
+ throw new IllegalArgumentException("broken URL: " + url); //$NON-NLS-1$
+ }
+
+ }
+ if ("file".equalsIgnoreCase(uri.getScheme())) { //$NON-NLS-1$
+ String auth = uri.getAuthority();
+ String path = uri.getPath();
+ if (path==null) path = uri.getRawPath();
+ if (path==null) path = uri.getSchemeSpecificPart();
+ if (path==null) path = uri.getRawSchemeSpecificPart();
+ if (path!=null) {
+ if (auth==null || "".equals(auth)) { //$NON-NLS-1$
+ // absolute filename in URI
+ return new File(path);
+ }
+ // relative filename in URI, extract it directly
+ return new File(auth+path);
+ }
+ }
+ throw new IllegalArgumentException("not a file URL: "+url); //$NON-NLS-1$
+ }
+
+ /** Convert a string to an URL according to several rules.
+ * <p>
+ * The rules are (the first succeeded is replied):
+ * <ul>
+ * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+ * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+ * <li>if <var>allowResourceSearch</var> is <code>true</code> and
+ * <var>urlDescription</var> starts with {@code "resource:"}, call
+ * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+ * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+ * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+ * parameter;</li>
+ * <li>assuming that the <var>urlDescription</var> is
+ * a filename, call {@link File#toURI()} to retreive an URI and then
+ * {@link URI#toURL()};</li>
+ * <li>If everything else failed, return <code>null</code>.</li>
+ * </ul>
+ *
+ * @param urlDescription is a string which is describing an URL.
+ * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+ * @return the URL.
+ * @throws IllegalArgumentException is the string could not be formatted to URL.
+ * @see Resources#getResource(String)
+ */
+ public static URL convertStringToUrl(String urlDescription, boolean allowResourceSearch) {
+ return convertStringToUrl(urlDescription, allowResourceSearch, true);
+ }
+
+ /** Convert a string to an URL according to several rules.
+ * <p>
+ * The rules are (the first succeeded is replied):
+ * <ul>
+ * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+ * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+ * <li>if <var>allowResourceSearch</var> is <code>true</code> and
+ * <var>urlDescription</var> starts with {@code "resource:"}, call
+ * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+ * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+ * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+ * parameter;</li>
+ * <li>if <var>repliesFileURL</var> is <code>true</code> and
+ * assuming that the <var>urlDescription</var> is
+ * a filename, call {@link File#toURI()} to retreive an URI and then
+ * {@link URI#toURL()};</li>
+ * <li>If everything else failed, return <code>null</code>.</li>
+ * </ul>
+ *
+ * @param urlDescription is a string which is describing an URL.
+ * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+ * @param repliesFileURL indicates if urlDescription is allowed to be a filename.
+ * @return the URL.
+ * @throws IllegalArgumentException is the string could not be formatted to URL.
+ * @see Resources#getResource(String)
+ */
+ public static URL convertStringToUrl(String urlDescription, boolean allowResourceSearch, boolean repliesFileURL) {
+ if (urlDescription==null || urlDescription.length()==0) return null;
+
+ try {
+ return new URL(urlDescription);
+ }
+ catch (MalformedURLException _) {
+ // ignore error
+ }
+
+ URL url;
+
+ if (allowResourceSearch) {
+
+ String resourceName;
+
+ if (urlDescription.toLowerCase().startsWith("resource:")) { //$NON-NLS-1$
+ resourceName = urlDescription.substring(9);
+ return Resources.getResource(resourceName);
+ }
+
+ resourceName = urlDescription;
+ url = Resources.getResource(resourceName);
+ if (url!=null) return url;
+ }
+ else if (urlDescription.toLowerCase().startsWith("resource:")) { //$NON-NLS-1$
+ return null;
+ }
+
+ if (repliesFileURL) {
+ try {
+ File file = new File(urlDescription);
+ URI uri = file.toURI();
+ return uri.toURL();
+ }
+ catch (MalformedURLException e) {
+ // ignore error
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Make the given filename absolute from the given root if it is not already absolute.
+ *
+ * @param filename is the name to make absolute.
+ * @param current is the current directory which permits to make absolute.
+ * @return an absolute filename.
+ */
+ public static File makeAbsolute(File filename, File current) {
+ if (filename==null) return null;
+ if (current!=null && !filename.isAbsolute()) {
+ try {
+ return new File(current.getCanonicalFile(), filename.getPath());
+ }
+ catch(IOException _) {
+ return new File(current.getAbsoluteFile(), filename.getPath());
+ }
+ }
+ return filename;
+ }
+
+ /** Replies if the given URL is using a protocol which could be map to files.
+ *
+ * @param url
+ * @return <code>true</code> if the given url is a "file", "http",
+ * "https", "ftp", "ssh", "jar" or "resource", otherwise <code>false</code>.
+ */
+ public static boolean isFileBasedURL(URL url) {
+ if (url!=null) {
+ String scheme = url.getProtocol();
+ if ("file".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ if ("http".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ if ("https".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ if ("ftp".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ if ("ssh".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ if ("jar".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ if ("resource".equalsIgnoreCase(scheme)) return true; //$NON-NLS-1$
+ }
+ return false;
+ }
+
+ /**
+ * Make the given filename absolute from the given root if it is not already absolute.
+ *
+ * @param filename is the name to make absolute.
+ * @param current is the current directory which permits to make absolute.
+ * @return an absolute filename.
+ */
+ public static URL makeAbsolute(URL filename, File current) {
+ if (filename==null) return null;
+ if (current!=null && isFileBasedURL(filename)) {
+ String scheme = filename.getProtocol();
+ if ("jar".equalsIgnoreCase(scheme)) { //$NON-NLS-1$
+ try {
+ String[] parts = filename.getPath().split(JAR_URL_FILE_ROOT);
+ URL u = makeAbsolute(new URL(parts[0]), current);
+ StringBuffer adr = new StringBuffer("jar:"); //$NON-NLS-1$
+ adr.append(u.toExternalForm());
+ for(int i=1; i<parts.length; i++) {
+ adr.append(JAR_URL_FILE_ROOT);
+ adr.append(parts[i]);
+ }
+ return new URL(adr.toString());
+ }
+ catch(MalformedURLException _) {
+ // Ignore error
+ }
+ }
+ else {
+ int port = filename.getPort();
+ try {
+ String absPath = filename.getPath();
+ if (!absPath.startsWith(URL_PATH_SEPARATOR)) {
+ URL rootUrl = current.toURI().toURL();
+ absPath = rootUrl.getPath()+URL_PATH_SEPARATOR+absPath;
+ return new URL(filename.getProtocol(), filename.getHost(), port, absPath);
+ }
+ }
+ catch (MalformedURLException e) {
+ //
+ }
+ }
+ }
+ return filename;
+ }
+
+ /**
+ * Make the given filename absolute from the given root if it is not already absolute.
+ *
+ * @param filename is the name to make absolute.
+ * @param current is the current directory which permits to make absolute.
+ * @return an absolute filename.
+ */
+ public static URL makeAbsolute(URL filename, URL current) {
+ if (current!=null && "file".equalsIgnoreCase(current.getProtocol())) { //$NON-NLS-1$
+ File cur = convertUrlToFile(current);
+ if (cur!=null) return makeAbsolute(filename, cur);
+ }
+ return filename;
+ }
+
+ /** Replies the parent URL for the given URL.
+ *
+ * @param url
+ * @return the parent URL
+ * @throws MalformedURLException
+ */
+ public static URL getParentURL(URL url) throws MalformedURLException {
+ String path = url.getPath();
+ String prefix, parentStr;
+
+ if ("jar".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+ int index = path.indexOf(JAR_URL_FILE_ROOT);
+ assert(index>0);
+ prefix = path.substring(0,index+1);
+ path = path.substring(index+1);
+ parentStr = URL_PATH_SEPARATOR;
+ }
+ else if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+ prefix = null;
+ parentStr = ".."+URL_PATH_SEPARATOR; //$NON-NLS-1$
+ }
+ else {
+ prefix = null;
+ parentStr = URL_PATH_SEPARATOR;
+ }
+
+ if (path==null || "".equals(path)) path = parentStr; //$NON-NLS-1$
+ int index = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+ if (index==-1) path = parentStr;
+ else if (index==path.length()-1) {
+ index = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR, index-1);
+ if (index==-1) path = parentStr;
+ else path = path.substring(0, index+1);
+ }
+ else path = path.substring(0, index+1);
+
+ if (prefix!=null) path = prefix + path;
+
+ return new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+ }
+
+}
+
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,203 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownServiceException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimetypesFileTypeMap;
+
+/**
+ * The class <code>FileURLConnection</code> is implementing
+ * connection between an URL and a local file.
+ * Instances of this class can be used both to
+ * read from and to write to the resource referenced by the file URL.
+ * <p>
+ * Supported header fields are:
+ * <ul>
+ * <li><code>content-type</code></li>
+ * <li><code>content-length</code></li>
+ * <li><code>last-modified</code></li>
+ * </ul>
+ *
+ * @author Alexandre WILLAUME <willaume@xxxxxxxxxxx>
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLConnection
+ */
+class FileURLConnection extends URLConnection {
+
+ private File file = null;
+
+ private String contentType = null;
+
+ /**
+ * @param url is the "file"-protocol url to use.
+ */
+ protected FileURLConnection(URL url) {
+ super(url);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getHeaderField(int n) {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ switch(n) {
+ case 0: // content-type
+ return this.contentType;
+ case 1: // content-length
+ return Long.toString(this.file.length());
+ case 2: // last-modified
+ return Long.toString(this.file.lastModified());
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getHeaderField(String name) {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ if ("content-type".equals(name)) { //$NON-NLS-1$
+ return this.contentType;
+ }
+ if ("content-length".equals(name)) { //$NON-NLS-1$
+ return Long.toString(this.file.length());
+ }
+ if ("last-modified".equals(name)) { //$NON-NLS-1$
+ return Long.toString(this.file.lastModified());
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getHeaderFieldKey(int n) {
+ switch(n) {
+ case 0:
+ return "content-type"; //$NON-NLS-1$
+ case 1:
+ return "content-length"; //$NON-NLS-1$
+ case 2:
+ return "last-modified"; //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<String,List<String>> getHeaderFields() {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ Map<String, List<String>> flds = new HashMap<String, List<String>>();
+ flds.put("content-type", singletonList(this.contentType)); //$NON-NLS-1$
+ flds.put("content-length", singletonList(Long.toString(this.file.length()))); //$NON-NLS-1$
+ flds.put("last-modified", singletonList(Long.toString(this.file.lastModified()))); //$NON-NLS-1$
+ return flds;
+ }
+
+ private List<String> singletonList(String value) {
+ if (value==null) return null;
+ return Collections.singletonList(value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void connect() throws IOException {
+ if (!this.connected) {
+ this.file = FileSystem.convertUrlToFile(this.url);
+ if (this.file==null)
+ throw new FileNotFoundException(this.url.toExternalForm());
+ this.contentType = new MimetypesFileTypeMap().getContentType(this.file);
+ this.connected = true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ connect();
+ if (getDoOutput()) {
+ OutputStream os = new FileOutputStream(this.file);
+ if (getUseCaches()) {
+ os = new BufferedOutputStream(os);
+ }
+ return os;
+ }
+ throw new UnknownServiceException("URL connection cannot do output"); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public InputStream getInputStream() throws IOException {
+ connect();
+ if (getDoInput()) {
+ InputStream is = new FileInputStream(this.file);
+ if (getUseCaches()) {
+ is = new BufferedInputStream(is);
+ }
+ return is;
+ }
+ throw new UnknownServiceException("URL connection cannot do input"); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+/**
+ * The class <code>FileURLStreamHandler</code> is supporting file protocol
+ * for URL streams. This stream protocol
+ * handler knows how to make a connection for "file" protocol.
+ * <p>
+ * In most cases, an instance of a <code>URLStreamHandler</code>
+ * subclass is not created directly by an application. Rather, the
+ * first time a protocol name is encountered when constructing a
+ * <code>URL</code>, the appropriate stream protocol handler is
+ * automatically loaded.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());</code>.
+ *
+ * @author Alexandre WILLAUME <willaume@xxxxxxxxxxx>
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandler
+ * @see FileURLStreamHandlerFactory
+ */
+class FileURLStreamHandler extends URLStreamHandler {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URLConnection openConnection(URL url) throws IOException {
+ if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+ return new FileURLConnection(url);
+ }
+ throw new UnsupportedOperationException("Unsupported protocol: "+url); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * This class defines a factory for <code>URL</code> stream
+ * "file" protocol handlers.
+ * <p>
+ * It is used by the <code>URL</code> class to create a
+ * <code>URLStreamHandler</code> for a "file" protocol.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());</code>.
+ *
+ * @author Alexandre WILLAUME <willaume@xxxxxxxxxxx>
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandlerFactory
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ */
+public class FileURLStreamHandlerFactory
+implements URLStreamHandlerFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ if ("file".equalsIgnoreCase(protocol)) //$NON-NLS-1$
+ return new FileURLStreamHandler();
+ // Force the default factory to retreive stream handler.
+ return null;
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/LibraryLoader.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/LibraryLoader.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/LibraryLoader.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,370 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/**
+ * This class provides more generic means for loading
+ * dynamical libraries.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:43:41 $
+ */
+public class LibraryLoader {
+
+ /**
+ * Loads a code file with the specified filename from the local file
+ * system as a dynamic library. The filename
+ * argument must be a complete path name.
+ * <p>
+ * The call <code>LibraryLoader.load(name)</code> is effectively equivalent
+ * to the call:
+ * <blockquote><pre>
+ * System.load(name)
+ * </pre></blockquote>
+ *
+ * @param filename is the file to load.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the file does not exist.
+ * @throws NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.System#load(java.lang.String)
+ */
+ public static void load(String filename) {
+ Runtime.getRuntime().load(filename);
+ }
+
+ /**
+ * Loads the system library specified by the <code>libname</code>
+ * argument. The manner in which a library name is mapped to the
+ * actual system library is system dependent.
+ * <p>
+ * The call <code>LibraryLoader.loadLibrary(name)</code> is effectively
+ * equivalent to the call
+ * <blockquote><pre>
+ * System.loadLibrary(name)
+ * </pre></blockquote>
+ *
+ * @param libname the name of the library.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the library does not exist.
+ * @throws NullPointerException if <code>libname</code> is
+ * <code>null</code>
+ * @see java.lang.System#loadLibrary(java.lang.String)
+ */
+ public static void loadLibrary(String libname) {
+ Runtime.getRuntime().loadLibrary(libname);
+ }
+
+ /**
+ * Loads a code file with the specified filename from the local file
+ * system as a dynamic library. The filename
+ * argument must be a complete path name.
+ * <p>
+ * The call <code>LibraryLoader.load(name)</code> is effectively equivalent
+ * to the call:
+ * <blockquote><pre>
+ * System.load(name.getAbsolutePath())
+ * </pre></blockquote>
+ *
+ * @param filename is the file to load.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the file does not exist.
+ * @throws NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.System#load(java.lang.String)
+ */
+ public static void load(File filename) {
+ Runtime.getRuntime().load(filename.getAbsolutePath());
+ }
+
+ /** Replies the URL for the specified library.
+ *
+ * @param libName is the name of the library
+ * @return the URL where the specified library was located.
+ */
+ public static URL findLibraryURL(String libName) {
+ return findLibraryURL(null,libName,null,null);
+ }
+
+ /** Replies the URL for the specified library.
+ * <p>
+ * The call <code>LibraryLoader.findLibraryURL(path,name)</code> is effectively equivalent
+ * to the call:
+ * <blockquote><pre>
+ * getClassLoader().getResource(path+System.mapLibraryName(name))
+ * </pre></blockquote>
+ *
+ * @param path is the resource's path where the library was located.
+ * @param libName is the name of the library
+ * @return the URL where the specified library was located.
+ */
+ public static URL findLibraryURL(String path, String libName) {
+ return findLibraryURL(path, libName, null, null);
+ }
+
+ private static URL findLibraryURL(String path, String libName, String platform, String arch) {
+ ClassLoader cl = ClassLoaderFinder.findClassLoader();
+ assert(cl!=null);
+ String resourcePath = path;
+ if (resourcePath==null) resourcePath = ""; //$NON-NLS-1$
+ else if ((resourcePath.length()>0)&&(!resourcePath.endsWith("/"))) { //$NON-NLS-1$
+ resourcePath += "/"; //$NON-NLS-1$
+ }
+ // Find the 64bits version of the DLL
+ String realLibName;
+ if (platform!=null) {
+ StringBuffer buf = new StringBuffer(libName);
+ buf.append("-"); //$NON-NLS-1$
+ buf.append(platform);
+ if (arch!=null) buf.append(arch);
+ realLibName = System.mapLibraryName(buf.toString());
+ int idx = realLibName.indexOf(libName);
+ if (idx>0) realLibName = realLibName.substring(idx);
+ }
+ else {
+ StringBuffer buf = new StringBuffer(libName);
+ if (arch!=null) buf.append(arch);
+ realLibName = System.mapLibraryName(buf.toString());
+ }
+ URL libRes = Resources.getResource(cl, resourcePath+realLibName);
+ if (libRes!=null) return libRes;
+ return Resources.getResource(cl,realLibName);
+ }
+
+ /**
+ * Loads a code file with the specified filename from the local file
+ * system as a dynamic library. The filename
+ * argument must be a complete path name.
+ *
+ * @param filename is the file to load.
+ * @throws IOException
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the file does not exist.
+ * @throws NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.System#load(java.lang.String)
+ */
+ public static void load(URL filename) throws IOException {
+ if (filename.getProtocol().equalsIgnoreCase("file")) { //$NON-NLS-1$
+ try {
+ load(new File(filename.toURI()));
+ }
+ catch (URISyntaxException e) {
+ throw new FileNotFoundException(filename.toExternalForm());
+ }
+ }
+ else {
+ // Create a tmp file to receive the library code.
+ String libName = System.mapLibraryName("javaDynLib"); //$NON-NLS-1$
+ String suffix = ".dll"; //$NON-NLS-1$
+ String prefix = "javaDynLib"; //$NON-NLS-1$
+ int pos = libName.lastIndexOf('.');
+ if (pos>=0) {
+ suffix = libName.substring(pos);
+ prefix = libName.substring(0,pos);
+ }
+ File f = File.createTempFile(prefix,suffix);
+
+ // Copy the library code into the local file
+ FileOutputStream outs = new FileOutputStream(f);
+ InputStream ins = filename.openStream();
+ byte[] buffer = new byte[2048];
+ int lu;
+ while ((lu=ins.read(buffer))>0) {
+ outs.write(buffer,0,lu);
+ }
+ ins.close();
+ outs.close();
+
+ // Load the library from the local file
+ load(f);
+
+ // Delete local file
+ f.deleteOnExit();
+ }
+ }
+
+ /**
+ * Search and load the dynamic library which is fitting the
+ * current operating system (32 or 64bits operating system...).
+ * A 64 bits library is assumed to be named <code>libname64.dll</code>
+ * on Windows® and <code>liblibname64.so</code> on Unix.
+ * A 32 bits library is assumed to be named <code>libname32.dll</code>
+ * on Windows® and <code>liblibname32.so</code> on Unix.
+ * A library which could be ran either on 32 and 64 platforms is assumed
+ * to be named <code>libname.dll</code> on Windows® and
+ * <code>liblibname.so</code> on Unix.
+ *
+ * @param libname is the name of the library.
+ * @throws IOException
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the file does not exist.
+ * @throws NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.System#load(java.lang.String)
+ */
+ public static void loadPlatformDependentLibrary(String libname) throws IOException {
+ loadPlatformDependentLibrary(null,libname);
+ }
+
+ /** Replies the data model of the current operating system: 32 or 64 bits.
+ *
+ * @return the integer which is corresponding to the data model, or <code>0</code> if
+ * it could not be determined.
+ */
+ static int getOperatingSystemArchitectureDataModel() {
+ String arch = System.getProperty("sun.arch.data.model"); //$NON-NLS-1$
+ if (arch!=null) {
+ try {
+ return Integer.parseInt(arch);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Search and load the dynamic library which is fitting the
+ * current operating system (32 or 64bits operating system...).
+ * A 64 bits library is assumed to be named <code>libname64.dll</code>
+ * on Windows® and <code>liblibname64.so</code> on Unix.
+ * A 32 bits library is assumed to be named <code>libname32.dll</code>
+ * on Windows® and <code>liblibname32.so</code> on Unix.
+ * A library which could be ran either on 32 and 64 platforms is assumed
+ * to be named <code>libname.dll</code> on Windows® and
+ * <code>liblibname.so</code> on Unix.
+ *
+ * @param path is the resource's path where the library was located.
+ * @param libname is the name of the library.
+ * @throws IOException
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the file does not exist.
+ * @throws NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.System#load(java.lang.String)
+ */
+ public static void loadPlatformDependentLibrary(String path, String libname) throws IOException {
+ loadPlatformDependentLibrary(libname, null, path);
+ }
+
+ private static URL getPlatformDependentLibrary(String[] paths, String libname, String platform) {
+ URL url;
+ int dataModel = getOperatingSystemArchitectureDataModel();
+ for(String path : paths) {
+ // Load the 64 library
+ if (dataModel==64) {
+ url = findLibraryURL(path, libname, platform, "64"); //$NON-NLS-1$
+ if (url!=null) return url;
+ }
+ // Load the 32 library
+ else if (dataModel==32) {
+ url = findLibraryURL(path, libname, platform, "32"); //$NON-NLS-1$
+ if (url!=null) return url;
+ }
+ // Load the multi-platform library
+ url = findLibraryURL(path, libname, platform, null);
+ if (url!=null) return url;
+ }
+ return null;
+ }
+
+ /**
+ * Search and load the dynamic library which is fitting the
+ * current operating system (32 or 64bits operating system...).
+ * A 64 bits library is assumed to be named <code>libname64.dll</code>
+ * on Windows® and <code>liblibname64.so</code> on Unix.
+ * A 32 bits library is assumed to be named <code>libname32.dll</code>
+ * on Windows® and <code>liblibname32.so</code> on Unix.
+ * A library which could be ran either on 32 and 64 platforms is assumed
+ * to be named <code>libname.dll</code> on Windows® and
+ * <code>liblibname.so</code> on Unix.
+ *
+ * @param libname is the name of the library.
+ * @param platform is the name of the current OS platform.
+ * @param paths are the resource's paths where the library was located.
+ * @throws IOException
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @throws UnsatisfiedLinkError if the file does not exist.
+ * @throws NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.System#load(java.lang.String)
+ */
+ static void loadPlatformDependentLibrary(String libname, String platform, String... paths) throws IOException {
+ URL url;
+ // Package version (according to Maven module)
+ url = getPlatformDependentLibrary(paths, libname, null);
+ if (url!=null) {
+ try {
+ load(url);
+ // library loaded
+ return;
+ }
+ catch(Throwable e) {
+ System.err.println("could not load "+url); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ }
+ // Eclipse version (according to Maven module)
+ if (platform!=null) {
+ url = getPlatformDependentLibrary(paths, libname, platform);
+ if (url!=null) {
+ try {
+ load(url);
+ // library loaded
+ return;
+ }
+ catch(Throwable e) {
+ System.err.println("could not load "+url); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // System-based loading
+ loadLibrary(libname);
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/MACNumber.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/MACNumber.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/MACNumber.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,379 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** A MACNumber is the unique number associated to a network interface.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see NetworkInterface
+ */
+public final class MACNumber {
+
+ /**
+ * Character that is used as separator inside MAC addresses.
+ */
+ public static final char MACNUMBER_SEPARATOR = '/';
+
+ /** Parse the specified string an repleis the corresponding MAC numbers.
+ *
+ * @param addresses is the string to parse
+ * @return a list of addresses.
+ * @throws IllegalArgumentException is the argument has not the right syntax.
+ */
+ public static MACNumber[] parse(String addresses) {
+ if ((addresses==null)||("".equals(addresses))) return new MACNumber[0]; //$NON-NLS-1$
+ String[] adrs = addresses.split(Character.toString(MACNUMBER_SEPARATOR));
+ ArrayList<MACNumber> list = new ArrayList<MACNumber>();
+ for (String adr : adrs) {
+ list.add(new MACNumber(adr));
+ }
+ MACNumber[] tab = new MACNumber[list.size()];
+ list.toArray(tab);
+ list.clear();
+ return tab;
+ }
+
+ /** Parse the specified string an repleis the corresponding MAC numbers.
+ *
+ * @param addresses is the string to parse
+ * @return a list of addresses.
+ * @throws IllegalArgumentException is the argument has not the right syntax.
+ */
+ public static String[] parseAsString(String addresses) {
+ if ((addresses==null)||("".equals(addresses))) return new String[0]; //$NON-NLS-1$
+ String[] adrs = addresses.split(Character.toString(MACNUMBER_SEPARATOR));
+ ArrayList<String> list = new ArrayList<String>();
+ for (String adr : adrs) {
+ list.add(new MACNumber(adr).toString());
+ }
+ String[] tab = new String[list.size()];
+ list.toArray(tab);
+ list.clear();
+ return tab;
+ }
+
+ /** Join the specified MAC numbers to reply a string.
+ *
+ * @param addresses is the list of mac addresses to join.
+ * @return the joined string.
+ */
+ public static String join(MACNumber... addresses) {
+ if ((addresses==null)||(addresses.length==0)) return null;
+ StringBuffer buf = new StringBuffer();
+ for (MACNumber number : addresses) {
+ if (buf.length()>0) buf.append(MACNUMBER_SEPARATOR);
+ buf.append(number);
+ }
+ return buf.toString();
+ }
+
+ /** Get all of the ethernet addresses associated with the local machine.
+ * <p>
+ * This method will try and find ALL of the ethernet adapters
+ * which are currently available on the system. This is heavily OS
+ * dependent and may not be supported on all platforms. When not
+ * supported, you should still get back a collection with the {@link
+ * #getPrimaryAdapter primary adapter} in it.
+ *
+ * @return the list of MAC numbers associated to the physical devices.
+ * @see #getPrimaryAdapter
+ */
+ public static Collection<MACNumber> getAllAdapters() {
+ List<MACNumber> av = new ArrayList<MACNumber>();
+ try {
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ if (interfaces!=null) {
+ NetworkInterface inter;
+ while (interfaces.hasMoreElements()) {
+ inter = interfaces.nextElement();
+ try {
+ byte[] addr = inter.getHardwareAddress();
+ if (addr!=null) av.add(new MACNumber(addr));
+ }
+ catch(SocketException _) {
+ //
+ }
+ }
+ }
+ }
+ catch(SocketException _) {
+ //
+ }
+ return av;
+ }
+
+ /** Get all of the internet address and ethernet address mappings
+ * on the local machine.
+ * <p>
+ * This method will try and find ALL of the ethernet adapters
+ * which are currently available on the system. This is heavily OS
+ * dependent and may not be supported on all platforms. When not
+ * supported, you should still get back a collection with the {@link
+ * #getPrimaryAdapterAddresses primary adapter} in it.
+ *
+ * @return the map internet address and ethernet address mapping.
+ * @see #getPrimaryAdapterAddresses
+ */
+ public static Map<InetAddress, MACNumber> getAllMappings() {
+ Map<InetAddress,MACNumber> av = new HashMap<InetAddress,MACNumber>();
+ try {
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ if (interfaces!=null) {
+ NetworkInterface inter;
+ MACNumber mac;
+ InetAddress inet;
+ while (interfaces.hasMoreElements()) {
+ inter = interfaces.nextElement();
+ try {
+ byte[] addr = inter.getHardwareAddress();
+ if (addr!=null) {
+ mac = new MACNumber(addr);
+ Enumeration<InetAddress> inets = inter.getInetAddresses();
+ while (inets.hasMoreElements()) {
+ inet = inets.nextElement();
+ av.put(inet, mac);
+ }
+ }
+ }
+ catch(SocketException _) {
+ //
+ }
+ }
+ }
+ }
+ catch(SocketException _) {
+ //
+ }
+ return av;
+ }
+
+ /** Try to determine the primary ethernet address of the machine.
+ *
+ * @return the primary MACNumber or <code>null</code>
+ */
+ public static MACNumber getPrimaryAdapter() {
+ try {
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ if (interfaces!=null) {
+ NetworkInterface inter;
+ while (interfaces.hasMoreElements()) {
+ inter = interfaces.nextElement();
+ try {
+ byte[] addr = inter.getHardwareAddress();
+ if (addr!=null) return new MACNumber(addr);
+ }
+ catch(SocketException _) {
+ //
+ }
+ }
+ }
+ }
+ catch(SocketException _) {
+ //
+ }
+ return null;
+ }
+
+ /** Try to determine the primary ethernet address of the machine and
+ * replies the associated internet addresses.
+ *
+ * @return the internet addresses of the primary network interface.
+ */
+ public static Collection<InetAddress> getPrimaryAdapterAddresses() {
+ try {
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ if (interfaces!=null) {
+ NetworkInterface inter;
+ while (interfaces.hasMoreElements()) {
+ inter = interfaces.nextElement();
+ try {
+ byte[] addr = inter.getHardwareAddress();
+ if (addr!=null) {
+ Collection<InetAddress> inetList = new ArrayList<InetAddress>();
+ Enumeration<InetAddress> inets = inter.getInetAddresses();
+ while (inets.hasMoreElements()) {
+ inetList.add(inets.nextElement());
+ }
+
+ return inetList;
+ }
+ }
+ catch(SocketException _) {
+ //
+ }
+ }
+ }
+ }
+ catch(SocketException _) {
+ //
+ }
+ return null;
+ }
+
+ /** Constant ethernet address object which has the "null address".
+ *
+ * <p>This constant can be used when you want a non-null
+ * MACAddress object reference, but want a invalid (or null)
+ * MAC address contained.
+ *
+ * @see #isNull()
+ */
+ public static final MACNumber NULL = new MACNumber();
+
+ /**
+ * Content of the MAC address.
+ */
+ private final byte[] bytes;
+
+
+ /** Constructs object with "null values" (address of "0:0:0:0:0:0").
+ */
+ public MACNumber() {
+ this.bytes = new byte[6];
+ }
+
+ /** Build a MACNumber from a set of bytes.
+ * The byte array must contains 6 elements.
+ *
+ * @param bytes is the list of bytes from which the address must be built.
+ * @throws IllegalArgumentException if the byte array does not corresponds to a valid MAC Number.
+ */
+ public MACNumber(byte[] bytes) {
+ if (bytes == null || bytes.length != 6) {
+ throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+ }
+ this.bytes = new byte[6];
+ System.arraycopy(bytes, 0, this.bytes, 0, 6);
+ }
+
+ /** Build a MACNumber from a string representation.
+ *
+ * @param address is the string representation of a MAC address
+ * @throws IllegalArgumentException if the byte array does not corresponds to a valid MAC Number.
+ * @see #toString()
+ */
+ public MACNumber(String address) {
+ if (address==null)
+ throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+ String[] parts = address.split(":"); //$NON-NLS-1$
+ if (parts.length!=6)
+ throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+ this.bytes = new byte[6];
+ try {
+ int val;
+ for(int i=0; i<6; i++) {
+ val = Integer.parseInt(parts[i],16);
+ this.bytes[i] = (byte)val;
+ }
+ }
+ catch(Exception _) {
+ throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof MACNumber)) return false;
+
+ byte[] bao = ((MACNumber) o).bytes;
+ if (bao.length != this.bytes.length) return false;
+
+ for (int i = 0; i < bao.length; i++) if (bao[i] != this.bytes[i]) return false;
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int blen = this.bytes.length;
+ if (blen == 0) return 0;
+
+ int hc = this.bytes[0];
+ for (int i = 1; i < blen; i++) {
+ hc *= 37;
+ hc += this.bytes[i];
+ }
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ int blen = this.bytes.length;
+ StringBuffer sb = new StringBuffer(blen*3);
+ for (int i = 0; i < blen; i++) {
+ int lo = this.bytes[i];
+ int hi = ((lo >> 4) & 0xF);
+ lo &= 0xF;
+ if (i != 0) sb.append(':');
+ sb.append(Character.forDigit(hi,16));
+ sb.append(Character.forDigit(lo,16));
+ }
+ return sb.toString();
+ }
+
+ /** Replies if all the MAC address number are equal to zero.
+ *
+ * @return <code>true</code> if all the bytes are zero.
+ * @see #NULL
+ */
+ public boolean isNull() {
+ for (int i = 0; i < this.bytes.length; i++) {
+ if (this.bytes[i]!=0) return false;
+ }
+ return true;
+ }
+
+ /** Replies the bytes that compose this MAC Address.
+ *
+ * @return a copy of the current bytes.
+ */
+ public byte[] getBytes() {
+ return this.bytes.clone();
+ }
+
+}
+
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystem.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystem.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystem.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,242 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.IOError;
+import java.io.IOException;
+
+/**
+ * This is a list of supported operating system.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.2 $ $Date: 2007-04-26 11:32:44 $
+ */
+public enum OperatingSystem {
+
+ /**
+ * Windows®.
+ */
+ WIN,
+
+ /**
+ * Linux distribution.
+ */
+ LINUX,
+
+ /**
+ * Solaris®.
+ */
+ SOLARIS,
+
+ /**
+ * Mac OS X®.
+ */
+ MACOSX,
+
+ /**
+ * Free BSD.
+ */
+ FREEBSD,
+
+ /**
+ * Net BSD.
+ */
+ NETBSD,
+
+ /**
+ * Standard BSD.
+ */
+ BSD,
+
+ /**
+ * Open BSD.
+ */
+ OPENBSD,
+
+ /**
+ * AIX®.
+ */
+ AIX,
+
+ /**
+ * HPUX®.
+ */
+ HPUX,
+
+ /**
+ * Unknown operating systems.
+ */
+ OTHER;
+
+ /** Replies if the current OperatingSystem constant is corresponding
+ * to the current operating system.
+ *
+ * @return <code>true</code> if the current operating system corresponds to this constant,
+ * otherwise <code>false</code>
+ */
+ public boolean isCurrentOS() {
+ return getCurrentOS()==this;
+ }
+
+ /** Replies of this OS is Unix compliant.
+ *
+ * @return <code>true</code> if this constant corresponds to a Unix-like operating system,
+ * otherwise <code>false</code>
+ */
+ public boolean isUnixCompliant() {
+ switch(this) {
+ case AIX:
+ case BSD:
+ case FREEBSD:
+ case HPUX:
+ case LINUX:
+ case MACOSX:
+ case NETBSD:
+ case OPENBSD:
+ case SOLARIS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+
+ /** Replies the name of the current OS.
+ *
+ * @return the name of the current operating system.
+ * @see System#getProperty(java.lang.String)
+ */
+ public static String getCurrentOSName() {
+ return System.getProperty("os.name"); //$NON-NLS-1$
+ }
+
+ /** Replies the version of the current OS.
+ *
+ * @return the version of the current operating system.
+ * @see System#getProperty(java.lang.String)
+ */
+ public static String getCurrentOSVersion() {
+ return System.getProperty("os.version"); //$NON-NLS-1$
+ }
+
+ /** Replies the current operating system.
+ *
+ * @return the current operating system constant.
+ */
+ public static OperatingSystem getCurrentOS() {
+ String os = System.getProperty("os.name").trim().toLowerCase(); //$NON-NLS-1$
+
+ /* Let's try to figure canonical OS name, just in case some
+ * JVMs use funny values (unlikely)
+ */
+ if (os.indexOf("windows") >= 0) { //$NON-NLS-1$
+ return WIN;
+ }
+ else if (os.indexOf("linux") >= 0) { //$NON-NLS-1$
+ return LINUX;
+ }
+ else if ((os.indexOf("solaris") >= 0)|| //$NON-NLS-1$
+ (os.indexOf("sunos") >= 0)) { //$NON-NLS-1$
+ return SOLARIS;
+ }
+ else if ((os.indexOf("mac os x") >= 0)|| //$NON-NLS-1$
+ (os.indexOf("macosx") >= 0)) { //$NON-NLS-1$
+ return MACOSX;
+ }
+ else if (os.indexOf("bsd") >= 0) { //$NON-NLS-1$
+ if (os.indexOf("freebsd") >= 0) { //$NON-NLS-1$
+ return FREEBSD;
+ }
+ else if (os.indexOf("netbsd") >= 0) { //$NON-NLS-1$
+ return NETBSD;
+ }
+ else if (os.indexOf("openbsd") >= 0) { //$NON-NLS-1$
+ return OPENBSD;
+ }
+ else { // default
+ return BSD;
+ }
+ }
+ else if (os.indexOf("aix") >= 0) { //$NON-NLS-1$
+ return AIX;
+ }
+ else if (os.indexOf("hp ux") >= 0) { //$NON-NLS-1$
+ return HPUX;
+ }
+ else {
+ return OTHER;
+ }
+ }
+
+ /** Replies the data model of the current operating system: 32 or 64 bits.
+ *
+ * @return the integer which is corresponding to the data model, or <code>0</code> if
+ * it could not be determined.
+ */
+ public static int getOperatingSystemArchitectureDataModel() {
+ return LibraryLoader.getOperatingSystemArchitectureDataModel();
+ }
+
+ /** Replies if the current operating system is 64bit.
+ *
+ * @return <code>true</code> if the operating system is 64bits, othewise
+ * <code>false</code>
+ */
+ public static boolean is64BitOperatingSystem() {
+ return getOperatingSystemArchitectureDataModel()==64;
+ }
+
+ /** Replies if the current operating system is 32bit.
+ *
+ * @return <code>true</code> if the operating system is 32bits, othewise
+ * <code>false</code>
+ */
+ public static boolean is32BitOperatingSystem() {
+ int dataModel = getOperatingSystemArchitectureDataModel();
+ return dataModel==32 || dataModel==0;
+ }
+
+ /** Get the OS serial number.
+ *
+ * @return the serial number associated to the current operating system.
+ */
+ public static native String getOSSerialNumber();
+
+ /** Get the OS UUID.
+ *
+ * @return an unique identifier for the current operating system.
+ */
+ public static native String getOSUUID();
+
+ static {
+ try {
+ LibraryLoader.loadPlatformDependentLibrary(
+ "josuuid", //$NON-NLS-1$
+ System.getProperty("os.name").trim().toLowerCase(), //$NON-NLS-1$
+ "org/arakhne/vmutil"); //$NON-NLS-1$
+ }
+ catch (IOException e) {
+ throw new IOError(e);
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * This class print on the standard output several informations
+ * about your operating system.
+ * These informations are extracted by the Java or the native
+ * libraries from <code>arakhneVmutils</code>.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class OperatingSystemInfo {
+
+ private static void showTitle(String title) {
+ System.out.print("#######################################\n# "); //$NON-NLS-1$
+ System.out.println(title);
+ System.out.println("#######################################"); //$NON-NLS-1$
+ }
+
+ private static void showPropertyValue(String name) {
+ showValue(name, System.getProperty(name));
+ }
+
+ private static void showValue(String name, String value) {
+ System.out.print(name);
+ System.out.print(" = "); //$NON-NLS-1$
+ System.out.println(value);
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+
+ showTitle("JRE Properties"); //$NON-NLS-1$
+
+ showPropertyValue("java.class.path"); //$NON-NLS-1$
+ showPropertyValue("java.library.path"); //$NON-NLS-1$
+ showPropertyValue("java.home"); //$NON-NLS-1$
+ showPropertyValue("os.name"); //$NON-NLS-1$
+ showPropertyValue("path.separator"); //$NON-NLS-1$
+ showPropertyValue("sun.arch.data.model"); //$NON-NLS-1$
+ showPropertyValue("user.dir"); //$NON-NLS-1$
+ showPropertyValue("user.name"); //$NON-NLS-1$
+
+ showTitle("OperatingSystem"); //$NON-NLS-1$
+
+ showValue("getCurrentOSName()", OperatingSystem.getCurrentOSName()); //$NON-NLS-1$
+ showValue("getCurrentOSVersion()", OperatingSystem.getCurrentOSVersion()); //$NON-NLS-1$
+ showValue("getOSSerialNumber()", OperatingSystem.getOSSerialNumber()); //$NON-NLS-1$
+ showValue("getOSUUID()", OperatingSystem.getOSUUID()); //$NON-NLS-1$
+ showValue("getOperatingSystemArchitectureDataModel()", Integer.toString(OperatingSystem.getOperatingSystemArchitectureDataModel())); //$NON-NLS-1$
+ showValue("getCurrentOS()", OperatingSystem.getCurrentOS().name()); //$NON-NLS-1$
+ showValue("is32BitOperatingSystem()", Boolean.toString(OperatingSystem.is32BitOperatingSystem())); //$NON-NLS-1$
+ showValue("is64BitOperatingSystem()", Boolean.toString(OperatingSystem.is64BitOperatingSystem())); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,465 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * This utility class provides a way to extend the reflection API and
+ * the Class class with autoboxing-compliant functions.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @since since JDK 1.5
+ */
+public class ReflectionUtil {
+
+ /**
+ * Determines if the specified <code>Object</code> is assignment-compatible
+ * with the object represented by the <code>Class</code>. This method extends
+ * {@link Class#isInstance(Object)} with autoboxing support.
+ *
+ * @param type is the class against which the object must be test
+ * @param obj is the object to check
+ * @return <code>true</code> if <code>obj</code> is an instance of the type
+ * @see Class#isInstance(Object)
+ */
+ public static boolean isInstance(Class<?> type, Object obj) {
+ assert(type!=null);
+ if (obj==null) return false;
+
+ // Test according to the Class's behaviour
+ if (type.isInstance(obj)) return true;
+
+ // Test according to autoboxing
+ if (type.isPrimitive()
+ &&
+ type!=Void.class && type!=void.class) {
+
+ if (type==Boolean.class) return boolean.class.isInstance(obj);
+ if (type==boolean.class) return Boolean.class.isInstance(obj);
+
+ if (type==Character.class) return char.class.isInstance(obj);
+ if (type==char.class) return Character.class.isInstance(obj);
+
+ if (type==Byte.class) return byte.class.isInstance(obj);
+ if (type==byte.class) return Byte.class.isInstance(obj);
+
+ if (type==Short.class) return short.class.isInstance(obj);
+ if (type==short.class) return Short.class.isInstance(obj);
+
+ if (type==Integer.class) return int.class.isInstance(obj);
+ if (type==int.class) return Integer.class.isInstance(obj);
+
+ if (type==Long.class) return long.class.isInstance(obj);
+ if (type==long.class) return Long.class.isInstance(obj);
+
+ if (type==Float.class) return float.class.isInstance(obj);
+ if (type==float.class) return Float.class.isInstance(obj);
+
+ if (type==Double.class) return double.class.isInstance(obj);
+ if (type==double.class) return Double.class.isInstance(obj);
+
+ if (type==Void.class) return void.class.isInstance(obj);
+ if (type==void.class) return Void.class.isInstance(obj);
+
+ assert false: "Unsupported primitive type"; //$NON-NLS-1$
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Determines if the <code>assignmentTarget</code> object is either the same as,
+ * or is a superclass or superinterface of, the class or interface
+ * represented by the specified
+ * <code>assignementSource</code> parameter. This method extends
+ * {@link Class#isAssignableFrom(Class)} with autoboxing support.
+ *
+ * @param assignementTarget is the class that is tested to be a super class.
+ * @param assignementSource is the class that is tested to be a sub class.
+ * @return <code>true</code> if an object of the <var>assignementSource</var> type
+ * could be assigned to a variable of <var>assignementTarget</var> type,
+ * otherwise <code>false</code>.
+ */
+ public static boolean isAssignableFrom(Class<?> assignementTarget, Class<?> assignementSource) {
+ assert(assignementSource!=null);
+ assert(assignementTarget!=null);
+
+ // Test according to the Class's behaviour
+ if (assignementTarget.isAssignableFrom(assignementSource)) return true;
+
+ // Test according to autoboxing
+ if (assignementTarget.isPrimitive() && assignementSource.isPrimitive()
+ &&
+ assignementTarget!=Void.class && assignementTarget!=void.class
+ &&
+ assignementSource!=Void.class && assignementSource!=void.class) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /** Replies the type that corresponds to the specified class.
+ * If the name corresponds to a primitive type, the low-level type
+ * will be replied.
+ * This method extends
+ * {@link Class#forName(String)} with autoboxing support.
+ *
+ * @param name is the name of the class to load.
+ * @return the loaded class
+ * @throws ClassNotFoundException if name names an
+ * unknown class or primitive
+ */
+ public static Class<?> forName(String name) throws ClassNotFoundException {
+ if (name == null || "".equals(name) || "null".equals(name) || "void".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return void.class;
+ }
+ if ("boolean".equals(name)) { //$NON-NLS-1$
+ return boolean.class;
+ }
+ if ("byte".equals(name)) { //$NON-NLS-1$
+ return byte.class;
+ }
+ if ("char".equals(name)) { //$NON-NLS-1$
+ return char.class;
+ }
+ if ("double".equals(name)) { //$NON-NLS-1$
+ return double.class;
+ }
+ if ("float".equals(name)) { //$NON-NLS-1$
+ return float.class;
+ }
+ if ("int".equals(name)) { //$NON-NLS-1$
+ return int.class;
+ }
+ if ("long".equals(name)) { //$NON-NLS-1$
+ return long.class;
+ }
+ if ("short".equals(name)) { //$NON-NLS-1$
+ return short.class;
+ }
+ return Class.forName(name);
+ }
+
+ /** Replies the type that corresponds to the specified class.
+ * If the name corresponds to a primitive type, the low-level type
+ * will be replied.
+ * This method extends
+ * {@link Class#forName(String)} with autoboxing support.
+ *
+ * @param name is the name of the class to load.
+ * @param loader is the class loader to use.
+ * @return the loaded class
+ * @throws ClassNotFoundException if name names an
+ * unknown class or primitive
+ */
+ public static Class<?> forName(String name, ClassLoader loader) throws ClassNotFoundException {
+ return forName(name, true, loader);
+ }
+
+ /** Replies the type that corresponds to the specified class.
+ * If the name corresponds to a primitive type, the low-level type
+ * will be replied.
+ * This method extends
+ * {@link Class#forName(String)} with autoboxing support.
+ *
+ * @param name is the name of the class to load.
+ * @param typeInitialization must be <code>true</code> to initialize the type, <code>false</code> otherwise.
+ * @param loader is the class loader to use.
+ * @return the loaded class
+ * @throws ClassNotFoundException if name names an
+ * unknown class or primitive
+ */
+ public static Class<?> forName(String name, boolean typeInitialization, ClassLoader loader) throws ClassNotFoundException {
+ if (name == null || "".equals(name) || "null".equals(name) || "void".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return void.class;
+ }
+ if ("boolean".equals(name)) { //$NON-NLS-1$
+ return boolean.class;
+ }
+ if ("byte".equals(name)) { //$NON-NLS-1$
+ return byte.class;
+ }
+ if ("char".equals(name)) { //$NON-NLS-1$
+ return char.class;
+ }
+ if ("double".equals(name)) { //$NON-NLS-1$
+ return double.class;
+ }
+ if ("float".equals(name)) { //$NON-NLS-1$
+ return float.class;
+ }
+ if ("int".equals(name)) { //$NON-NLS-1$
+ return int.class;
+ }
+ if ("long".equals(name)) { //$NON-NLS-1$
+ return long.class;
+ }
+ if ("short".equals(name)) { //$NON-NLS-1$
+ return short.class;
+ }
+ return Class.forName(name, typeInitialization, loader);
+ }
+
+ /**
+ * Replies the list of the classes in the given package.
+ * @param pkg is the package to explore.
+ * @return the list of classes in the package.
+ */
+ public static Collection<Class<?>> getPackageClasses(Package pkg) {
+ return getPackageClasses(pkg.getName());
+ }
+
+ /**
+ * Replies the list of the classes in the given package.
+ * @param packageName is the name of the package to explore.
+ * @return the list of classes in the package.
+ */
+ public static Collection<Class<?>> getPackageClasses(String packageName) {
+ Collection<Class<?>> classes = new ArrayList<Class<?>>();
+
+ String[] entries = System.getProperty("java.class.path").split(System.getProperty("path.separator")); //$NON-NLS-1$//$NON-NLS-2$
+ String lentry;
+
+ for(String path : entries) {
+ lentry = path.toLowerCase();
+ if(lentry.endsWith(".jar") || lentry.endsWith(".war")) { //$NON-NLS-1$//$NON-NLS-2$
+ getPackageClassesFromJar(classes, path, packageName);
+ }else{
+ getPackageClassesFromFileSystem(classes, path, packageName);
+ }
+
+ }
+
+ return classes;
+ }
+
+ private static String basename(String name) {
+ int idx = name.lastIndexOf('/');
+ if (idx>=0 && idx<name.length()) {
+ return name.substring(idx+1);
+ }
+ return name;
+ }
+
+ private static String filename(String name) {
+ String basename = basename(name);
+ int idx = basename.indexOf('.');
+ if (idx>=0 && idx<basename.length()) {
+ return basename.substring(0,idx);
+ }
+ return name;
+ }
+
+ private static void getPackageClassesFromJar(Collection<Class<?>> classes, String jarFilename, String packageName) {
+ try {
+ JarFile jarFile = new JarFile(jarFilename);
+ String packagePath = packageName.replace(".", "/"); //$NON-NLS-1$//$NON-NLS-2$
+
+ Enumeration<JarEntry> entries = jarFile.entries();
+ JarEntry entry;
+ String entryPath, entryClassname;
+
+ while (entries.hasMoreElements()) {
+ entry = entries.nextElement();
+ entryPath = entry.getName();
+
+ // In package and not inner class
+ if (entryPath.startsWith(packagePath)
+ && !entryPath.endsWith("/") //$NON-NLS-1$
+ && !entryPath.contains("$")) { //$NON-NLS-1$
+ entryClassname = packageName + "." + filename(entryPath); //$NON-NLS-1$
+ try {
+ classes.add(Class.forName(entryClassname));
+ }
+ catch(ClassNotFoundException _) {
+ //
+ }
+ }
+ }
+ }
+ catch(IOException _) {
+ //
+ }
+ }
+
+ private static void getPackageClassesFromFileSystem(Collection<Class<?>> classes, String directory, String packageName) {
+ String packagePath = packageName.replace(".", File.separator); //$NON-NLS-1$
+ File packageDirectory = new File(directory, packagePath);
+ String entryClassname;
+
+ if (packageDirectory.isDirectory()) {
+ for(String entryPath : packageDirectory.list()) {
+
+ // In package and not inner class
+ if (!entryPath.contains("$")) { //$NON-NLS-1$
+ entryClassname = packageName + "." + FileSystem.shortBasename(entryPath); //$NON-NLS-1$
+ try {
+ classes.add(Class.forName(entryClassname));
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Replies the list of all the subclasses of the given class
+ * in the current classpath.
+ *
+ * @param <T> is the type of the superclass.
+ * @param className is the name of the class to explore.
+ * @return the list of subclasses.
+ */
+ public static <T> Collection<Class<? extends T>> getSubClasses(Class<T> className) {
+ Collection<Class<? extends T>> list = new ArrayList<Class<? extends T>>();
+ getSubClasses(className, true, true, true, list);
+ return list;
+ }
+
+ /**
+ * Replies the list of all the subclasses of the given class
+ * in the current classpath.
+ *
+ * @param <T> is the type of the superclass.
+ * @param className is the name of the class to explore.
+ * @param allowAbstract is <code>true</code> to allow abstract classes to be put in the replied list
+ * @param allowInterface is <code>true</code> to allow interfaces to be put in the replied list.
+ * @param allowEnum is <code>true</code> to allow enumeration to be put in the replied list.
+ * @param result is the list of subclasses which will be filled by this function.
+ */
+ public static <T> void getSubClasses(Class<T> className, boolean allowAbstract, boolean allowInterface, boolean allowEnum, Collection<Class<? extends T>> result) {
+ String[] entries = System.getProperty("java.class.path").split(System.getProperty("path.separator")); //$NON-NLS-1$//$NON-NLS-2$
+ String lentry;
+
+ for(String path : entries) {
+ lentry = path.toLowerCase();
+ if(lentry.endsWith(".jar") || lentry.endsWith(".war")) { //$NON-NLS-1$//$NON-NLS-2$
+ getSubClassesFromJar(result, path, className, allowAbstract, allowInterface, allowEnum);
+ }else{
+ getSubClassesFromFileSystem(result, path, className, allowAbstract, allowInterface, allowEnum);
+ }
+
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> void getSubClassesFromJar(Collection<Class<? extends T>> classes, String jarFilename, Class<T> className, boolean allowAbstract, boolean allowInterface, boolean allowEnum) {
+ try {
+ JarFile jarFile = new JarFile(jarFilename);
+ String classN = className.getCanonicalName();
+ if (classN!=null) {
+ Enumeration<JarEntry> entries = jarFile.entries();
+ JarEntry entry;
+ String entryPath, entryClassname;
+
+ while (entries.hasMoreElements()) {
+ entry = entries.nextElement();
+ entryPath = entry.getName();
+
+ // In package and not inner class
+ if (entryPath.endsWith(".class") //$NON-NLS-1$
+ && !entryPath.contains("$")) { //$NON-NLS-1$
+ entryClassname = entryPath.substring(0, entryPath.length()-6).replaceAll(File.separator, "."); //$NON-NLS-1$
+ try {
+ Class<?> clazz = Class.forName(entryClassname);
+ if ((className.isAssignableFrom(clazz))
+ &&(allowAbstract || !Modifier.isAbstract(clazz.getModifiers()))
+ &&(allowInterface || !clazz.isInterface())
+ &&(allowEnum || !clazz.isEnum()))
+ classes.add((Class<? extends T>)clazz);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ }
+ }
+ }
+ catch(IOException _) {
+ //
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> void getSubClassesFromFileSystem(Collection<Class<? extends T>> classes, String directory, Class<T> className, boolean allowAbstract, boolean allowInterface, boolean allowEnum) {
+ String classN = className.getCanonicalName();
+ if (classN!=null) {
+ List<String> directories = new ArrayList<String>();
+ directories.add(""); //$NON-NLS-1$
+
+ String ldir, entryClassname;
+ File dir, fullFile;
+
+ while (!directories.isEmpty()) {
+ ldir = directories.remove(0);
+ dir = new File(directory, ldir);
+ if (dir.isDirectory()) {
+ for(String entryPath : dir.list()) {
+
+ fullFile = new File(dir,entryPath);
+
+ if (fullFile.isDirectory()) {
+ if (ldir==null || "".equals(ldir)) { //$NON-NLS-1$
+ directories.add(entryPath);
+ }
+ else {
+ directories.add(new File(ldir,entryPath).toString());
+ }
+ }
+ // In package and not inner class
+ else if (entryPath.endsWith(".class") //$NON-NLS-1$
+ && !entryPath.contains("$")) { //$NON-NLS-1$
+ assert(ldir!=null);
+ entryClassname = ldir.replaceAll(File.separator, ".") + "." + FileSystem.shortBasename(entryPath); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ Class<?> clazz = Class.forName(entryClassname);
+ if ((className.isAssignableFrom(clazz))
+ &&(allowAbstract || !Modifier.isAbstract(clazz.getModifiers()))
+ &&(allowInterface || !clazz.isInterface())
+ &&(allowEnum || !clazz.isEnum()))
+ classes.add((Class<? extends T>)clazz);
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+
+/**
+ * The exception <code>ResourceNotFoundException</code> is
+ * thrown when a required Java resource was not found.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class ResourceNotFoundException extends IOException {
+
+ private static final long serialVersionUID = 4951959393164477007L;
+
+ /**
+ */
+ public ResourceNotFoundException() {
+ super();
+ }
+
+ /**
+ * @param message
+ */
+ public ResourceNotFoundException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param cause
+ */
+ public ResourceNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public ResourceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLConnection.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLConnection.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLConnection.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,154 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The class <code>ResourceURLConnection</code> is implementing
+ * connection between an URL and a Java resource.
+ * Instances of this class can be used to
+ * read from the resource referenced by the resource URL. Write
+ * is allowed depending on where resource is located.
+ * <p>
+ * Supported header fields are the same as the real resource URL
+ * (basicaly, file or jar protocols).
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLConnection
+ */
+class ResourceURLConnection extends URLConnection {
+
+ private URL location = null;
+ private URLConnection connection = null;
+
+ /**
+ * @param url is the "file"-protocol url to use.
+ */
+ protected ResourceURLConnection(URL url) {
+ super(url);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getHeaderField(int n) {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ return this.connection.getHeaderField(n);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getHeaderField(String name) {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ return this.connection.getHeaderField(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getHeaderFieldKey(int n) {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ return this.connection.getHeaderFieldKey(n);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<String,List<String>> getHeaderFields() {
+ try {
+ connect();
+ }
+ catch(IOException e) {
+ throw new IllegalStateException(e);
+ }
+ return this.connection.getHeaderFields();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void connect() throws IOException {
+ if (!this.connected) {
+ this.location = Resources.getResource(this.url.getFile());
+ if (this.location==null)
+ throw new ResourceNotFoundException(this.url.toExternalForm());
+ this.connection = this.location.openConnection();
+ if (this.connection==null)
+ throw new ResourceNotFoundException(this.url.toExternalForm());
+ this.connection.setDoInput(getDoInput());
+ this.connection.setDoOutput(getDoOutput());
+ this.connection.setAllowUserInteraction(getAllowUserInteraction());
+ this.connection.setConnectTimeout(getConnectTimeout());
+ this.connection.setDefaultUseCaches(getDefaultUseCaches());
+ this.connection.setReadTimeout(getReadTimeout());
+ this.connection.setIfModifiedSince(getIfModifiedSince());
+ this.connected = true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ connect();
+ return this.connection.getOutputStream();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public InputStream getInputStream() throws IOException {
+ connect();
+ return this.connection.getInputStream();
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandler.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandler.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandler.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,60 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+/**
+ * The class <code>ResourceURLStreamHandler</code> is supporting resource protocol
+ * for URL streams. This stream protocol
+ * handler knows how to make a connection for "resource" protocol.
+ * <p>
+ * In most cases, an instance of a <code>URLStreamHandler</code>
+ * subclass is not created directly by an application. Rather, the
+ * first time a protocol name is encountered when constructing a
+ * <code>URL</code>, the appropriate stream protocol handler is
+ * automatically loaded.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new ResourceURLStreamHandlerFactory());</code>.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandler
+ * @see ResourceURLStreamHandlerFactory
+ */
+class ResourceURLStreamHandler extends URLStreamHandler {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URLConnection openConnection(URL url) throws IOException {
+ if ("resource".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+ return new ResourceURLConnection(url);
+ }
+ throw new UnsupportedOperationException("Unsupported protocol: "+url); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandlerFactory.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandlerFactory.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ResourceURLStreamHandlerFactory.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * This class defines a factory for <code>URL</code> stream
+ * "resource" protocol handlers.
+ * <p>
+ * It is used by the <code>URL</code> class to create a
+ * <code>URLStreamHandler</code> for a "resource" protocol.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new ResourceURLStreamHandlerFactory());</code>.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandlerFactory
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ */
+public class ResourceURLStreamHandlerFactory
+implements URLStreamHandlerFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ if ("resource".equalsIgnoreCase(protocol)) //$NON-NLS-1$
+ return new ResourceURLStreamHandler();
+ // Force the default factory to retreive stream handler.
+ return null;
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Resources.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Resources.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/Resources.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,152 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * This utility class provides to load resources according to
+ * several heuristics:<ul>
+ * <li>search the resource in class paths;</li>
+ * <li>search the resource in ./resources subdirectory in class paths.</li>
+ * </ul>
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @since since JDK 1.5
+ */
+public class Resources {
+
+ /**
+ * Replies the URL of a resource.
+ * <p>
+ * You may use Unix-like syntax to write the resource path, ie.
+ * you may use slashs to separate filenames, and may not start the
+ * path with a slash.
+ *
+ * @param path is the absolute path of the resource.
+ * @return the url of the resource or <code>null</code> if the resource was
+ * not found in class paths.
+ */
+ public static URL getResource(String path) {
+ return getResource(ClassLoaderFinder.findClassLoader(), path);
+ }
+
+ /**
+ * Replies the URL of a resource.
+ * <p>
+ * You may use Unix-like syntax to write the resource path, ie.
+ * you may use slashs to separate filenames, and may not start the
+ * path with a slash.
+ *
+ * @param clazz is the class which is restricting the scope of the search.
+ * @param path is the absolute path of the resource.
+ * @return the url of the resource or <code>null</code> if the resource was
+ * not found in class paths.
+ */
+ public static URL getResource(Class<?> clazz, String path) {
+ return getResource(clazz.getClassLoader(), path);
+ }
+
+ /**
+ * Replies the URL of a resource.
+ * <p>
+ * You may use Unix-like syntax to write the resource path, ie.
+ * you may use slashs to separate filenames, and may not start the
+ * path with a slash.
+ *
+ * @param classLoader is the research scope.
+ * @param path is the absolute path of the resource.
+ * @return the url of the resource or <code>null</code> if the resource was
+ * not found in class paths.
+ */
+ public static URL getResource(ClassLoader classLoader, String path) {
+ String resourcePath = path;
+ if (path.startsWith("/")) { //$NON-NLS-1$
+ resourcePath = path.substring(1);
+ }
+ URL url = classLoader.getResource(resourcePath);
+ if (url==null) {
+ // Try to find in ./resources sub directory
+ url = classLoader.getResource("resources/"+resourcePath); //$NON-NLS-1$
+ }
+ return url;
+ }
+
+ /**
+ * Replies the input stream of a resource.
+ * <p>
+ * You may use Unix-like syntax to write the resource path, ie.
+ * you may use slashs to separate filenames, and may not start the
+ * path with a slash.
+ *
+ * @param path is the absolute path of the resource.
+ * @return the url of the resource or <code>null</code> if the resource was
+ * not found in class paths.
+ */
+ public static InputStream getResourceAsStream(String path) {
+ return getResourceAsStream(ClassLoaderFinder.findClassLoader(), path);
+ }
+
+ /**
+ * Replies the input stream of a resource.
+ * <p>
+ * You may use Unix-like syntax to write the resource path, ie.
+ * you may use slashs to separate filenames, and may not start the
+ * path with a slash.
+ *
+ * @param clazz is the class which is restricting the scope of the search.
+ * @param path is the absolute path of the resource.
+ * @return the url of the resource or <code>null</code> if the resource was
+ * not found in class paths.
+ */
+ public static InputStream getResourceAsStream(Class<?> clazz, String path) {
+ return getResourceAsStream(clazz.getClassLoader(), path);
+ }
+
+ /**
+ * Replies the input stream of a resource.
+ * <p>
+ * You may use Unix-like syntax to write the resource path, ie.
+ * you may use slashs to separate filenames, and may not start the
+ * path with a slash.
+ *
+ * @param classLoader is the research scope.
+ * @param path is the absolute path of the resource.
+ * @return the url of the resource or <code>null</code> if the resource was
+ * not found in class paths.
+ */
+ public static InputStream getResourceAsStream(ClassLoader classLoader, String path) {
+ String resourcePath = path;
+ if (path.startsWith("/")) { //$NON-NLS-1$
+ resourcePath = path.substring(1);
+ }
+ InputStream is = classLoader.getResourceAsStream(resourcePath);
+ if (is==null) {
+ // Try to find in ./resources sub directory
+ is = classLoader.getResourceAsStream("resources/"+resourcePath); //$NON-NLS-1$
+ }
+ return is;
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,119 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.util.EmptyStackException;
+import java.util.Stack;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * This class permits to centralize the identify of the thread service providers.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class ThreadServiceFinder {
+
+ private static final Stack<ThreadServiceProvider> __services = new Stack<ThreadServiceProvider>();
+
+ static {
+ // Add the default provider
+ __services.push(new DefaultProvider());
+ }
+
+ /**
+ * Replies the current service provider.
+ *
+ * @return the thread service provider or <code>null</code>
+ */
+ public static ThreadServiceProvider getProvider() {
+ try {
+ return __services.peek();
+ }
+ catch(EmptyStackException _) {
+ return null;
+ }
+ }
+
+ /**
+ * Add a preferred provider.
+ *
+ * @param provider is the preferred thread service provider
+ */
+ public static void addPreferredProvider(ThreadServiceProvider provider) {
+ __services.push(provider);
+ }
+
+ /**
+ * Remove a provider.
+ *
+ * @param provider is the preferred thread service provider
+ */
+ public static void removeProvider(ThreadServiceProvider provider) {
+ __services.remove(provider);
+ }
+
+ /**
+ * Remove a provider.
+ */
+ public static void removeProvider() {
+ __services.pop();
+ }
+
+ /**
+ * @author Stéphane GALLAND <stephane.galland@xxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid fr.utbm.set
+ * @mavenartifactid setutil
+ */
+ static class DefaultProvider implements ThreadServiceProvider {
+
+ private ExecutorService __executor_service = null;
+
+ private ScheduledExecutorService __scheduled_executor_service = null;
+
+ /** {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ public ExecutorService getExecutorService() {
+ if (this.__executor_service==null) {
+ this.__executor_service = Executors.newCachedThreadPool();
+ }
+ return this.__executor_service;
+ }
+
+ /** {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ public ScheduledExecutorService getScheduledExecutorService() {
+ if (this.__scheduled_executor_service==null) {
+ this.__scheduled_executor_service = Executors.newScheduledThreadPool(3);
+ }
+ return this.__scheduled_executor_service;
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * This interface describes a provider of thread's service..
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public interface ThreadServiceProvider {
+
+ /** Replies the thread executor for this provider.
+ *
+ * @return the default executor service.
+ */
+ public ExecutorService getExecutorService();
+
+ /** Replies the scheduled thread executor for this provider.
+ *
+ * @return the default scheduled executor service.
+ */
+ public ScheduledExecutorService getScheduledExecutorService();
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/VMCommandLine.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/VMCommandLine.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/VMCommandLine.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,749 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2004-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+/**
+ * This utility class permits to get the java command line for the current VM.
+ *
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class VMCommandLine {
+
+ private static Class<?> classToLaunch = null;
+ private static boolean analyzed = false;
+ private static SortedMap<String,List<Object>> commandLineOptions = null;
+ private static String[] commandLineParameters = null;
+
+ /** Replies a binary executable filename depending of the current platform.
+ *
+ * @param name is the name which must be converted into a binary executable filename.
+ * @return the binary executable filename.
+ */
+ public static String getExecutableFilename(String name) {
+ if (OperatingSystem.WIN.isCurrentOS()) return name+".exe"; //$NON-NLS-1$
+ return name;
+ }
+
+ /** Replies the current java VM binary.
+ *
+ * @return the binary executable filename that was used to launch the virtual machine.
+ */
+ public static String getVMBinary() {
+ String java_home = System.getProperty("java.home"); //$NON-NLS-1$
+ File bin_dir = new File(new File(java_home),"bin"); //$NON-NLS-1$
+ if (bin_dir.isDirectory()) {
+ File exec = new File(bin_dir,getExecutableFilename("javaw")); //$NON-NLS-1$
+ if (exec.isFile()) {
+ return exec.getAbsolutePath();
+ }
+ exec = new File(bin_dir,getExecutableFilename("java")); //$NON-NLS-1$
+ if (exec.isFile()) {
+ return exec.getAbsolutePath();
+ }
+ }
+ return null;
+ }
+
+ /** Run a new VM with the class path of the current VM.
+ *
+ * @param class_to_launch is the class to launch.
+ * @param additional_params is the list of additional parameters
+ * @return the process that is running the new virtual machine, neither <code>null</code>
+ * @throws IOException
+ */
+ public static Process launchVM(Class<?> class_to_launch, String... additional_params) throws IOException {
+ String java_bin = getVMBinary();
+ if (java_bin==null) throw new FileNotFoundException("java"); //$NON-NLS-1$
+ long totalMemory = Runtime.getRuntime().maxMemory() / 1024;
+ String classpath = System.getProperty("java.class.path"); //$NON-NLS-1$
+ String user_dir = System.getProperty("user.dir"); //$NON-NLS-1$
+ String[] params = new String[additional_params.length+5];
+ params[0] = java_bin;
+ params[1] = "-Xmx"+totalMemory+"k"; //$NON-NLS-1$ //$NON-NLS-2$
+ params[2] = "-classpath"; //$NON-NLS-1$
+ params[3] = classpath;
+ params[4] = class_to_launch.getCanonicalName();
+ System.arraycopy(additional_params,0,params,5,additional_params.length);
+ return Runtime.getRuntime().exec(params,null,new File(user_dir));
+ }
+
+ /** Save parameters that permit to relaunch a VM with
+ * {@link #relaunchVM()}.
+ *
+ * @param class_to_launch is the class which contains a <code>main</code>.
+ * @param parameters is the parameters to pass to the <code>main</code>.
+ */
+ public static void saveVMParameters(Class<?> class_to_launch, String... parameters) {
+ classToLaunch = class_to_launch;
+ commandLineParameters = parameters;
+ if (commandLineOptions!=null) commandLineOptions.clear();
+ commandLineOptions = null;
+ analyzed = false;
+ }
+
+ /** Save parameters that permit to relaunch a VM with
+ * {@link #relaunchVM()}.
+ *
+ * @param class_to_launch is the class which contains a <code>main</code>.
+ * @param parameters is the parameters to pass to the <code>main</code>.
+ */
+ public static void saveVMParametersIfNotSet(Class<?> class_to_launch, String... parameters) {
+ if (classToLaunch==null) {
+ saveVMParameters(class_to_launch, parameters);
+ }
+ }
+
+ /** Launch a VM with the same parameters as ones saved by
+ * {@link #saveVMParameters(Class, String[])}.
+ *
+ * @return the process that is running the new virtual machine, neither <code>null</code>
+ * @throws IOException
+ */
+ public static Process relaunchVM() throws IOException {
+ if (classToLaunch==null) return null;
+ return launchVM(classToLaunch, getAllCommandLineParameters());
+ }
+
+ /** Replies the command line including the options and the standard parameters.
+ *
+ * @return the command line.
+ */
+ public static String[] getAllCommandLineParameters() {
+ int osize = commandLineOptions==null ? 0 : commandLineOptions.size();
+ int psize = commandLineParameters==null ? 0 : commandLineParameters.length;
+ int tsize = (osize>0 && psize>0) ? 1 : 0;
+ List<String> params = new ArrayList<String>(osize+tsize);
+ if (osize>0) {
+ List<Object> values;
+ String name, prefix, v;
+ for(Entry<String,List<Object>> entry : commandLineOptions.entrySet()) {
+ name = entry.getKey();
+ prefix = (name.length()>1) ? "--" : "-"; //$NON-NLS-1$ //$NON-NLS-2$
+ values = entry.getValue();
+ if (values==null || values.isEmpty()) {
+ params.add(prefix+name);
+ }
+ else {
+ for(Object value : values) {
+ if (value!=null) {
+ v = value.toString();
+ if (v!=null && v.length()>0) {
+ params.add(prefix+name+"="+v); //$NON-NLS-1$
+ }
+ else {
+ params.add(prefix+name);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (tsize>0) params.add("--"); //$NON-NLS-1$
+
+ String[] tab = new String[params.size()+psize];
+ params.toArray(tab);
+ params.clear();
+
+ if (psize>0)
+ System.arraycopy(commandLineParameters, 0, tab, osize+tsize, psize);
+
+ return tab;
+ }
+
+ /** Replies the command line parameters.
+ *
+ * @return the list of the parameters on the command line
+ */
+ public static String[] getCommandLineParameters() {
+ return commandLineParameters==null ? new String[0] : commandLineParameters;
+ }
+
+ /** Shift the command line parameters by one on the left.
+ * The first parameter is removed from the list.
+ *
+ * @return the removed element or <code>null</code>
+ */
+ public static String shiftCommandLineParameters() {
+ String removed = null;
+ if (commandLineParameters!=null) {
+ if (commandLineParameters.length==0) {
+ commandLineParameters = null;
+ }
+ else if (commandLineParameters.length==1) {
+ removed = commandLineParameters[0];
+ commandLineParameters = null;
+ }
+ else {
+ removed = commandLineParameters[0];
+ String[] newTab = new String[commandLineParameters.length-1];
+ System.arraycopy(commandLineParameters,1,newTab,0,commandLineParameters.length-1);
+ commandLineParameters = newTab;
+ }
+ }
+ return removed;
+ }
+
+ /** Replies the command line options.
+ *
+ * @return the list of options passed on the command line
+ */
+ public static Map<String,List<Object>> getCommandLineOptions() {
+ if (commandLineOptions!=null)
+ return Collections.unmodifiableSortedMap(commandLineOptions);
+ return Collections.emptyMap();
+ }
+
+ /** Replies one command option.
+ *
+ * @param name is the name of the option
+ * @return the option value or <code>null</code> if the option is not on the command line.
+ */
+ public static List<Object> getCommandLineOption(String name) {
+ if (commandLineOptions!=null) {
+ if (commandLineOptions.containsKey(name)) {
+ List<Object> value = commandLineOptions.get(name);
+ return value==null ? Collections.emptyList() : value;
+ }
+ }
+ return null;
+ }
+
+ /** Replies if an option was specified on the command line.
+ *
+ * @param name is the name of the option
+ * @return <code>true</code> if the option was found on the command line, otherwise <code>false</code>.
+ */
+ public static boolean hasCommandLineOption(String name) {
+ return (commandLineOptions!=null && commandLineOptions.containsKey(name));
+ }
+
+ private static boolean registerOptionValue(SortedMap<String,List<Object>> options, String name, Object value, OptionType type) {
+ boolean success = true;
+
+ Object optValue = value;
+
+ List<Object> values = options.get(name);
+ if (values==null) {
+ values = new ArrayList<Object>();
+ options.put(name, values);
+ }
+ switch(type) {
+ case AUTO_INCREMENTED:
+ {
+ long v;
+ if (values.isEmpty()) v = -1;
+ else {
+ optValue = values.get(0);
+ if (optValue==null) v = 0;
+ else if (!(optValue instanceof Number)) {
+ v = Long.parseLong(optValue.toString());
+ }
+ else {
+ v = ((Number)optValue).longValue();
+ }
+ }
+ if (values.isEmpty()) values.add(Long.valueOf(v+1));
+ else values.set(0, Long.valueOf(v+1));
+ }
+ break;
+ case FLAG:
+ if (optValue==null) {
+ if (values.isEmpty())
+ optValue = Boolean.TRUE;
+ else
+ optValue = values.get(0);
+ }
+ else if (!(optValue instanceof Boolean)) {
+ optValue = Boolean.parseBoolean(optValue.toString());
+ }
+ if (values.isEmpty()) values.add(optValue);
+ else values.set(0, optValue);
+ break;
+ case MANDATORY_BOOLEAN:
+ case OPTIONAL_BOOLEAN:
+ if (optValue==null) {
+ optValue = Boolean.TRUE;
+ }
+ else if (!(optValue instanceof Boolean)) {
+ optValue = Boolean.parseBoolean(optValue.toString());
+ }
+ values.add(optValue);
+ break;
+ case MANDATORY_FLOAT:
+ case OPTIONAL_FLOAT:
+ try {
+ if (optValue==null) {
+ optValue = Double.valueOf(0.);
+ }
+ else if (!(optValue instanceof Number)) {
+ optValue = Double.parseDouble(optValue.toString());
+ }
+ else {
+ optValue = Double.valueOf(((Number)optValue).doubleValue());
+ }
+ }
+ catch(NumberFormatException e) {
+ if (type.isOptional()) {
+ success = false;
+ optValue = Double.valueOf(0.);
+ }
+ else throw e;
+ }
+ values.add(optValue);
+ break;
+ case MANDATORY_INTEGER:
+ case OPTIONAL_INTEGER:
+ try {
+ if (optValue==null) {
+ optValue = Long.valueOf(0);
+ }
+ else if (!(optValue instanceof Number)) {
+ optValue = Long.parseLong(optValue.toString());
+ }
+ else {
+ optValue = Long.valueOf(((Number)optValue).longValue());
+ }
+ }
+ catch(NumberFormatException e) {
+ if (type.isOptional()) {
+ success = false;
+ optValue = Long.valueOf(0);
+ }
+ else throw e;
+ }
+ values.add(optValue);
+ break;
+ case MANDATORY_STRING:
+ case OPTIONAL_STRING:
+ values.add(optValue==null ? "" : optValue.toString()); //$NON-NLS-1$
+ break;
+ case SIMPLE:
+ values.add(optValue);
+ break;
+ }
+
+ return success;
+ }
+
+ /** Analyse the command line to extract the options.
+ * <p>
+ * The options will be recognized thanks to the <var>optionDefinitions</var>.
+ * Each entry of <var>optionDefinitions</var> describes an option. They must
+ * have one of the following formats:
+ * <ul>
+ * <li>{@code name}: a simple option without value or flag,</li>
+ * <li>{@code name=s}: an option with a mandatory string value,</li>
+ * <li>{@code name:s}: an option with an optional string value,</li>
+ * <li>{@code name=i}: an option with a mandatory integer value,</li>
+ * <li>{@code name:i}: an option with an optional integer value,</li>
+ * <li>{@code name=f}: an option with a mandatory floating-point value,</li>
+ * <li>{@code name:f}: an option with an optional floating-point value,</li>
+ * <li>{@code name=b}: an option with a mandatory boolean value,</li>
+ * <li>{@code name:b}: an option with an optional boolean value,</li>
+ * <li>{@code name+}: an option with an autoincremented integer value,</li>
+ * <li>{@code name!}: an option which could be flaged or not: {@code --name} or {@code --noname}.</li>
+ * </ul>
+ *
+ * @param optionDefinitions is the list of definitions of the available command line options.
+ */
+ public static void splitOptionsAndParameters(String... optionDefinitions) {
+ if (analyzed) return;
+
+ List<String> params = new ArrayList<String>();
+ SortedMap<String,List<Object>> options = new TreeMap<String,List<Object>>();
+ String opt;
+
+ // Analyze definitions
+ Map<String,OptionType> defs = new TreeMap<String,OptionType>();
+ for (String def : optionDefinitions) {
+ if (def.endsWith("!")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-1);
+ defs.put(opt, OptionType.FLAG);
+ registerOptionValue(options, opt, Boolean.FALSE, OptionType.FLAG);
+ }
+ else if (def.endsWith("+")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-1);
+ defs.put(opt, OptionType.AUTO_INCREMENTED);
+ registerOptionValue(options, opt, Long.valueOf(0), OptionType.AUTO_INCREMENTED);
+ }
+ else if (def.endsWith("=b")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.MANDATORY_BOOLEAN);
+ }
+ else if (def.endsWith(":b")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.OPTIONAL_BOOLEAN);
+ }
+ else if (def.endsWith("=f")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.MANDATORY_FLOAT);
+ }
+ else if (def.endsWith(":f")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.OPTIONAL_FLOAT);
+ }
+ else if (def.endsWith("=i")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.MANDATORY_INTEGER);
+ }
+ else if (def.endsWith(":i")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.OPTIONAL_INTEGER);
+ }
+ else if (def.endsWith("=s")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.MANDATORY_STRING);
+ }
+ else if (def.endsWith(":s")) { //$NON-NLS-1$
+ opt = def.substring(0, def.length()-2);
+ defs.put(opt, OptionType.OPTIONAL_STRING);
+ }
+ else {
+ defs.put(def, OptionType.SIMPLE);
+ }
+ }
+
+ int idx;
+ String base, nbase, val;
+ OptionType type;
+ OptionType waitingValue = null;
+ String valueOptionName = null;
+ boolean allParameters = false;
+ boolean success;
+
+ for(String param : commandLineParameters) {
+ if (allParameters) {
+ params.add(param);
+ continue;
+ }
+
+ if (waitingValue!=null && waitingValue.isMandatory()) {
+ // Expect a value as the next parameter
+ success = registerOptionValue(options, valueOptionName, param, waitingValue);
+ waitingValue = null;
+ valueOptionName = null;
+ if (success) continue;
+ }
+
+ if ("--".equals(param)) { //$NON-NLS-1$
+ if (waitingValue!=null) {
+ registerOptionValue(options, valueOptionName, null, waitingValue);
+ waitingValue = null;
+ valueOptionName = null;
+ }
+ allParameters = true;
+ continue;
+ }
+ else if ((File.separatorChar!='/')&&(param.startsWith("/"))) { //$NON-NLS-1$
+ opt = param.substring(1);
+ }
+ else if (param.startsWith("--")) { //$NON-NLS-1$
+ opt = param.substring(2);
+ }
+ else if (param.startsWith("-")) { //$NON-NLS-1$
+ opt = param.substring(1);
+ }
+ else if (waitingValue!=null) {
+ success = registerOptionValue(options, valueOptionName, param, waitingValue);
+ waitingValue = null;
+ valueOptionName = null;
+ if (!success) params.add(param);
+ continue;
+ }
+ else {
+ params.add(param);
+ continue;
+ }
+
+ if (waitingValue!=null) {
+ success = registerOptionValue(options, valueOptionName, param, waitingValue);
+ waitingValue = null;
+ valueOptionName = null;
+ if (success) continue;
+ }
+
+ idx = opt.indexOf('=');
+ if (idx>0) {
+ base = opt.substring(0,idx);
+ val = opt.substring(idx+1);
+ }
+ else {
+ base = opt;
+ val = null;
+ }
+
+ nbase = null;
+ type = defs.get(base);
+ if (type==null && base.toLowerCase().startsWith("no")) { //$NON-NLS-1$
+ nbase = base.substring(2);
+ type = defs.get(nbase);
+ }
+ if (type!=null) {
+ switch(type) {
+ case FLAG:
+ if (nbase==null)
+ registerOptionValue(options, base, Boolean.TRUE, type);
+ else
+ registerOptionValue(options, nbase, Boolean.FALSE, type);
+ break;
+ case MANDATORY_FLOAT:
+ case MANDATORY_BOOLEAN:
+ case MANDATORY_INTEGER:
+ case MANDATORY_STRING:
+ case OPTIONAL_FLOAT:
+ case OPTIONAL_BOOLEAN:
+ case OPTIONAL_INTEGER:
+ case OPTIONAL_STRING:
+ if (val!=null) {
+ registerOptionValue(options, base, val, type);
+ }
+ else {
+ waitingValue = type;
+ valueOptionName = base;
+ }
+ break;
+ default:
+ registerOptionValue(options, base, val, type);
+ }
+ }
+ else {
+ // Not a recognized option, assuming simple
+ registerOptionValue(options, base, val, OptionType.SIMPLE);
+ }
+ }
+
+ if (waitingValue!=null && waitingValue.isMandatory()) {
+ throw new IllegalStateException("expected a value for command line option "+valueOptionName); //$NON-NLS-1$
+ }
+
+ commandLineParameters = new String[params.size()];
+ params.toArray(commandLineParameters);
+ params.clear();
+
+ commandLineOptions = options;
+
+ analyzed = true;
+ }
+
+ /**
+ * Create a interface to the command line options.
+ *
+ * @param class_to_launch is the class which contains a <code>main</code>.
+ * @param parameters is the parameters to pass to the <code>main</code>.
+ * @see #saveVMParametersIfNotSet(Class, String[])
+ */
+ public VMCommandLine(Class<?> class_to_launch, String... parameters) {
+ saveVMParametersIfNotSet(class_to_launch, parameters);
+ }
+
+ /**
+ * Create a interface to the command line options.
+ *
+ * @param class_to_launch is the class which contains a <code>main</code>.
+ * @param optionDefinitions is the list of definitions of the available command line options.
+ * @param parameters is the parameters to pass to the <code>main</code>.
+ * @see #saveVMParametersIfNotSet(Class, String[])
+ * @see #splitOptionsAndParameters(String[])
+ */
+ public VMCommandLine(Class<?> class_to_launch, String[] optionDefinitions, String... parameters) {
+ saveVMParametersIfNotSet(class_to_launch, parameters);
+ splitOptionsAndParameters(optionDefinitions);
+ }
+
+ /**
+ * Create a interface to the command line options.
+ *
+ * @see #VMCommandLine(Class, String[], String[])
+ * @see #VMCommandLine(Class, String[])
+ */
+ public VMCommandLine() {
+ if (classToLaunch==null) {
+ throw new IllegalArgumentException("you must call the other constructor previously"); //$NON-NLS-1$
+ }
+ }
+
+ /** Replies if the given option is present on the command line.
+ *
+ * @param optionLabel is the name of the option
+ * @return <code>true</code> if the option is present, otherwise <code>false</code>
+ */
+ public boolean hasOption(String optionLabel) {
+ return hasCommandLineOption(optionLabel);
+ }
+
+ /** Replies the first value of the option.
+ *
+ * @param optionLabel is the name of the option
+ * @return the option value or <code>null</code> if the option is not present or has no value.
+ */
+ public Object getFirstOptionValue(String optionLabel) {
+ List<Object> options = getCommandLineOption(optionLabel);
+ if (options==null || options.isEmpty()) return null;
+ return options.get(0);
+ }
+
+ /** Replies the values of the option.
+ *
+ * @param optionLabel is the name of the option
+ * @return the option values or <code>null</code> if the option is not present.
+ */
+ public List<Object> getOptionValues(String optionLabel) {
+ List<Object> options = getCommandLineOption(optionLabel);
+ if (options==null) return null;
+ return Collections.unmodifiableList(options);
+ }
+
+ /** Replies the parameters on the command line that are not options.
+ *
+ * @return the parameters.
+ */
+ public String[] getParameters() {
+ return getCommandLineParameters();
+ }
+
+ /** Shift the command line parameters by one on the left.
+ * The first parameter is removed from the list.
+ *
+ * @return the removed element or <code>null</code>
+ */
+ public String shiftParameters() {
+ return shiftCommandLineParameters();
+ }
+
+ /** Replies the count of parameters on the command line that are not options.
+ *
+ * @return the count of parameters
+ */
+ public int getParameterCount() {
+ return getCommandLineParameters().length;
+ }
+
+ /** Replies the parameter at the specified index.
+ *
+ * @param index
+ * @return the value of the parameter.
+ * @throws IndexOutOfBoundsException
+ */
+ public String getParameterAt(int index) {
+ return getCommandLineParameters()[index];
+ }
+
+ /** Replies if the given index corresponds to a command line parameter.
+ *
+ * @param index
+ * @return <code>true</code> if the given index corresponds to a parameter,
+ * otherwise <code>false</code>
+ * @throws IndexOutOfBoundsException
+ */
+ public boolean isParameterExists(int index) {
+ String[] params = getCommandLineParameters();
+ return index>=0 && index<params.length && params[index]!=null;
+ }
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+ private static enum OptionType {
+
+ /**
+ * a simple option without value or flag.
+ */
+ SIMPLE,
+
+ /** an option with a mandatory string value.
+ */
+ MANDATORY_STRING,
+
+ /** an option with an optional string value.
+ */
+ OPTIONAL_STRING,
+
+ /** an option with a mandatory integer value.
+ */
+ MANDATORY_INTEGER,
+
+ /** an option with an optional integer value.
+ */
+ OPTIONAL_INTEGER,
+
+ /** an option with a mandatory floating-point value.
+ */
+ MANDATORY_FLOAT,
+
+ /** an option with an optional floating-point value.
+ */
+ OPTIONAL_FLOAT,
+
+ /** an option with a mandatory boolean value.
+ */
+ MANDATORY_BOOLEAN,
+
+ /** an option with an optional boolean value.
+ */
+ OPTIONAL_BOOLEAN,
+
+ /** an option with an auto-incremented integer value.
+ */
+ AUTO_INCREMENTED,
+
+ /** an option which could be flaged or not: {@code --name} or {@code --noname}.
+ */
+ FLAG;
+
+ /** Replies if the value is mandatory.
+ *
+ * @return <code>true</code> if the value is mandatory, otherwise <code>false</code>
+ */
+ public boolean isMandatory() {
+ return this==MANDATORY_BOOLEAN
+ || this==MANDATORY_FLOAT
+ || this==MANDATORY_STRING
+ || this==MANDATORY_INTEGER;
+ }
+
+ /** Replies if the value is optional.
+ *
+ * @return <code>true</code> if the value is not mandatory, otherwise <code>false</code>
+ */
+ public boolean isOptional() {
+ return this==OPTIONAL_BOOLEAN
+ || this==OPTIONAL_FLOAT
+ || this==OPTIONAL_STRING
+ || this==OPTIONAL_INTEGER;
+ }
+
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/main/resources/AUTHORS
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/resources/AUTHORS (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/resources/AUTHORS 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1 @@
+Stephane GALLAND <galland@xxxxxxxxxxx>
Added: tags/afc-2.0/arakhneVmutils/java/src/main/resources/COPYING
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/resources/COPYING (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/resources/COPYING 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
Added: tags/afc-2.0/arakhneVmutils/java/src/main/resources/Changelog
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/resources/Changelog (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/resources/Changelog 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,42 @@
+arakhneVmutils-4.1
+
+* Add a more generic getSubClasses() function in ReflectionUtil class.
+
+-- Stephane GALLAND <galland@xxxxxxxxxxx> Fri, 03 Apr 2009 20:12:44 +0200
+
+arakhneVmutils-4.0
+
+* Add function getSubClasses() in ReflectionUtil class.
+
+-- Stephane GALLAND <galland@xxxxxxxxxxx> Fri, 03 Apr 2009 01:03:45 +0200
+
+arakhneVmutils-3.0
+
+* Add class ReflectionUtil.
+
+-- Stephane GALLAND <galland@xxxxxxxxxxx> Tue, 10 Mar 2009 10:51:07 +0100
+
+arakhneVmutils-2.2
+
+* Bug fix: the FileSystem#split(File) function should not use the
+ absolute path of the given file.
+
+-- Stephane GALLAND <galland@xxxxxxxxxxx> Thu, 05 Mar 2009 15:08:29 +0100
+
+arakhneVmutils-2.1
+
+* HAL changed the name of the properties where the serial number and
+ system UUID were stored. Reflect this change in josuuid.
+* OperatingSystem is now able to indicate if the current operating
+ system is 32 or 64 bits compliant.
+* LibraryLoader is now able to load 64 or 32 bits library accordingly
+ to the current operating system.
+
+-- Stephane GALLAND <galland@xxxxxxxxxxx> Wed, 10 Dec 2008 14:33:19 +0100
+
+arakhneVmutils-1.0
+
+ * First public release
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Sat, 04 Oct 2008 09:51:52 +0200
+
Added: tags/afc-2.0/arakhneVmutils/java/src/main/resources/VERSION
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/main/resources/VERSION (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/main/resources/VERSION 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1 @@
+arakhneVmutils 4.1
Added: tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileSystemTest.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileSystemTest.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileSystemTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,807 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/**
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public class FileSystemTest extends TestCase {
+
+ private static final File f1 = new File("/home/test.x.z.z"); //$NON-NLS-1$
+ private static final File f2 = new File("/home"); //$NON-NLS-1$
+ private static final File pf1 = f1.getParentFile();
+ private static final File pf2 = f2.getParentFile();
+ private static final URL u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u13, u14, u15;
+ private static final URL pu1, pu2, pu3, pu7, pu13;
+ private static final String TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.z?toto#frag"; //$NON-NLS-1$
+ private static final String JOIN_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.z/home/test.x.z.z?toto#frag"; //$NON-NLS-1$
+ private static final String PARENT_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/"; //$NON-NLS-1$
+ private static final String WOEXT_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z?toto#frag"; //$NON-NLS-1$
+ private static final String REPEXT_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.toto?toto#frag"; //$NON-NLS-1$
+ private static final String TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.z"; //$NON-NLS-1$
+ private static final String PARENT_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/"; //$NON-NLS-1$
+ private static final String JOIN_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.z/home/test.x.z.z"; //$NON-NLS-1$
+ private static final String WOEXT_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z"; //$NON-NLS-1$
+ private static final String REPEXT_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.toto"; //$NON-NLS-1$
+ private static final String JARPART_TEST_URL2 = "file:/home/test/j.jar"; //$NON-NLS-1$
+ private static final File f3 = new File("/home/test/j.jar"); //$NON-NLS-1$
+ private static final File f4 = new File("/org/arakhne/vmutil/file.x.z.z"); //$NON-NLS-1$
+ private static final String TEST_URL3 = "jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/file.x.z.z"; //$NON-NLS-1$
+ private static final String PARENT_TEST_URL3 = "jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/"; //$NON-NLS-1$
+ private static final String JARPART_TEST_URL3 = "jar:http://www.arakhne.org/j.jar!/inner/myjar.jar"; //$NON-NLS-1$
+ private static final String JOIN_TEST_URL3 = "jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/file.x.z.z/home/test.x.z.z"; //$NON-NLS-1$
+
+ static {
+ try {
+ u1 = f1.toURI().toURL();
+ u2 = f2.toURI().toURL();
+ u3 = new URL(TEST_URL1);
+ u4 = new URL(JOIN_TEST_URL1);
+ u5 = new URL(WOEXT_TEST_URL1);
+ u6 = new URL(REPEXT_TEST_URL1);
+ u7 = new URL(TEST_URL2);
+ u8 = new URL(JOIN_TEST_URL2);
+ u9 = new URL(WOEXT_TEST_URL2);
+ u10 = new URL(REPEXT_TEST_URL2);
+ u11 = new URL(JARPART_TEST_URL2);
+ u13 = new URL(TEST_URL3);
+ u14 = new URL(JARPART_TEST_URL3);
+ u15 = new URL(JOIN_TEST_URL3);
+ pu1 = pf1.toURI().toURL();
+ pu2 = pf2.toURI().toURL();
+ pu3 = new URL(PARENT_TEST_URL1);
+ pu7 = new URL(PARENT_TEST_URL2);
+ pu13 = new URL(PARENT_TEST_URL3);
+ }
+ catch(Throwable e) {
+ throw new AssertionFailedError(e.getLocalizedMessage());
+ }
+ }
+
+ /**
+ */
+ public void tetIsJarURLURL() {
+ assertFalse(FileSystem.isJarURL(u1));
+ assertFalse(FileSystem.isJarURL(u2));
+ assertFalse(FileSystem.isJarURL(u3));
+ assertTrue(FileSystem.isJarURL(u7));
+ assertTrue(FileSystem.isJarURL(u13));
+ }
+
+ /**
+ */
+ public void testGetJarURLURL() {
+ assertNull(FileSystem.getJarURL(u1));
+ assertNull(FileSystem.getJarURL(u2));
+ assertNull(FileSystem.getJarURL(u3));
+ assertEquals(u11, FileSystem.getJarURL(u7));
+ assertEquals(u14, FileSystem.getJarURL(u13));
+ }
+
+ /**
+ */
+ public void testGetJarFileURL() {
+ assertNull(FileSystem.getJarFile(u1));
+ assertNull(FileSystem.getJarFile(u2));
+ assertNull(FileSystem.getJarFile(u3));
+ assertEquals(f4, FileSystem.getJarFile(u7));
+ assertEquals(f4, FileSystem.getJarFile(u13));
+ }
+
+ /**
+ * @throws MalformedURLException
+ */
+ public void testToJarURLFileFile() throws MalformedURLException {
+ assertEquals(u7, FileSystem.toJarURL(f3, f4));
+ }
+
+ /**
+ * @throws MalformedURLException
+ */
+ public void testToJarURLFileString() throws MalformedURLException {
+ assertEquals(u7, FileSystem.toJarURL(f3, f4.getPath()));
+ }
+
+ /**
+ * @throws MalformedURLException
+ */
+ public void testToJarURLURLFile() throws MalformedURLException {
+ assertEquals(u7, FileSystem.toJarURL(u11, f4));
+ }
+
+ /**
+ * @throws MalformedURLException
+ */
+ public void testToJarURLURLString() throws MalformedURLException {
+ assertEquals(u7, FileSystem.toJarURL(u11, f4.getPath()));
+ }
+
+ /**
+ */
+ public void testDirnameFile() {
+ assertEquals(pf1, FileSystem.dirname(f1));
+ assertEquals(pf2, FileSystem.dirname(f2));
+ }
+
+ /**
+ */
+ public void testDirnameURL() {
+ assertEquals(pu1, FileSystem.dirname(u1));
+ assertEquals(pu2, FileSystem.dirname(u2));
+ assertEquals(pu3, FileSystem.dirname(u3));
+ assertEquals(pu7, FileSystem.dirname(u7));
+ assertEquals(pu13, FileSystem.dirname(u13));
+ }
+
+ /**
+ */
+ public void testLargeBasenameString() {
+ assertEquals("test.x.z.z", FileSystem.largeBasename(f1.getAbsolutePath())); //$NON-NLS-1$
+ assertEquals("home", FileSystem.largeBasename(f2.getAbsolutePath())); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testLargeBasenameFile() {
+ assertEquals("test.x.z.z", FileSystem.largeBasename(f1)); //$NON-NLS-1$
+ assertEquals("home", FileSystem.largeBasename(f2)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testLargeBasenameURL() {
+ assertEquals("test.x.z.z", FileSystem.largeBasename(u1)); //$NON-NLS-1$
+ assertEquals("home", FileSystem.largeBasename(u2)); //$NON-NLS-1$
+ assertEquals("file.x.z.z", FileSystem.largeBasename(u3)); //$NON-NLS-1$
+ assertEquals("file.x.z.z", FileSystem.largeBasename(u7)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testBasenameString() {
+ assertEquals("test.x.z", FileSystem.basename(f1.getAbsolutePath())); //$NON-NLS-1$
+ assertEquals("home", FileSystem.basename(f2.getAbsolutePath())); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testBasenameFile() {
+ assertEquals("test.x.z", FileSystem.basename(f1)); //$NON-NLS-1$
+ assertEquals("home", FileSystem.basename(f2)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testBasenameURL() {
+ assertEquals("test.x.z", FileSystem.basename(u1)); //$NON-NLS-1$
+ assertEquals("home", FileSystem.basename(u2)); //$NON-NLS-1$
+ assertEquals("file.x.z", FileSystem.basename(u3)); //$NON-NLS-1$
+ assertEquals("file.x.z", FileSystem.basename(u7)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testShortBasenameString() {
+ assertEquals("test", FileSystem.shortBasename(f1.getAbsolutePath())); //$NON-NLS-1$
+ assertEquals("home", FileSystem.shortBasename(f2.getAbsolutePath())); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testShortBasenameFile() {
+ assertEquals("test", FileSystem.shortBasename(f1)); //$NON-NLS-1$
+ assertEquals("home", FileSystem.shortBasename(f2)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testShortBasenameURL() {
+ assertEquals("test", FileSystem.shortBasename(u1)); //$NON-NLS-1$
+ assertEquals("home", FileSystem.shortBasename(u2)); //$NON-NLS-1$
+ assertEquals("file", FileSystem.shortBasename(u3)); //$NON-NLS-1$
+ assertEquals("file", FileSystem.shortBasename(u7)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testExtensionFile() {
+ assertEquals(".z", FileSystem.extension(f1)); //$NON-NLS-1$
+ assertEquals("", FileSystem.extension(f2)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testExtensionURL() {
+ assertEquals(".z", FileSystem.extension(u1)); //$NON-NLS-1$
+ assertEquals("", FileSystem.extension(u2)); //$NON-NLS-1$
+ assertEquals(".z", FileSystem.extension(u3)); //$NON-NLS-1$
+ assertEquals(".z", FileSystem.extension(u7)); //$NON-NLS-1$
+ assertEquals(".z", FileSystem.extension(u13)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testExtensionsFile() {
+ assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(f1))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ assertTrue(Arrays.equals(new String[0], FileSystem.extensions(f2)));
+ }
+
+ /**
+ */
+ public void testExtensionsURL() {
+ assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(u1))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ assertTrue(Arrays.equals(new String[0], FileSystem.extensions(u2)));
+ assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(u3))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(u7))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /**
+ */
+ public void testSplitFile() {
+ assertTrue(Arrays.equals(
+ new String[] {
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z", //$NON-NLS-1$
+ },
+ FileSystem.split(f1)));
+ assertTrue(Arrays.equals(
+ new String[] {
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ },
+ FileSystem.split(f2)));
+ }
+
+ /**
+ */
+ public void testSplitURL() {
+ String[] tab;
+
+ tab = FileSystem.split(u1);
+ assertTrue(Arrays.equals(
+ new String[] {
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z", //$NON-NLS-1$
+ },
+ tab));
+
+ tab = FileSystem.split(u2);
+ assertTrue(Arrays.equals(
+ new String[] {
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ },
+ tab));
+
+ tab = FileSystem.split(u7);
+ assertTrue(Arrays.equals(
+ new String[] {
+ "", //$NON-NLS-1$
+ "org", //$NON-NLS-1$
+ "arakhne", //$NON-NLS-1$
+ "vmutil", //$NON-NLS-1$
+ "file.x.z.z", //$NON-NLS-1$
+ },
+ tab));
+
+ tab = FileSystem.split(u13);
+ assertTrue(Arrays.equals(
+ new String[] {
+ "", //$NON-NLS-1$
+ "org", //$NON-NLS-1$
+ "arakhne", //$NON-NLS-1$
+ "vmutil", //$NON-NLS-1$
+ "file.x.z.z", //$NON-NLS-1$
+ },
+ tab));
+ }
+
+ /**
+ */
+ public void testJoinFileStringArray() {
+ assertEquals(new File(new File(f1, "home"), "test.x.z.z"), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.join(f1,
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testJoinFileFileArray() {
+ assertEquals(new File(new File(f1, "home"), "test.x.z.z"), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.join(f1,
+ new File("home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ assertEquals(new File(new File(f1, "home"), "test.x.z.z"), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.join(f1,
+ new File(File.separator+"home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testJoinURLStringArray() throws Exception {
+ assertEquals(new File(new File(f1, "home"), "test.x.z.z").toURI().toURL(), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.join(u1,
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z")); //$NON-NLS-1$
+
+ assertEquals(u4,
+ FileSystem.join(u3,
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z")); //$NON-NLS-1$
+
+ assertEquals(u8,
+ FileSystem.join(u7,
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z")); //$NON-NLS-1$
+
+ assertEquals(u15,
+ FileSystem.join(u13,
+ "", //$NON-NLS-1$
+ "home", //$NON-NLS-1$
+ "test.x.z.z")); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testJoinURLFileArray() throws Exception {
+ assertEquals(new File(new File(f1, "home"), "test.x.z.z").toURI().toURL(), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.join(u1,
+ new File("home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ assertEquals(new File(new File(f1, "home"), "test.x.z.z").toURI().toURL(), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.join(u1,
+ new File(File.separator+"home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ assertEquals(u4,
+ FileSystem.join(u3,
+ new File(File.separator+"home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ assertEquals(u8,
+ FileSystem.join(u7,
+ new File(File.separator+"home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ assertEquals(u15,
+ FileSystem.join(u13,
+ new File(File.separator+"home"), //$NON-NLS-1$
+ new File("test.x.z.z"))); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testHasExtensionFileString() {
+ assertTrue(FileSystem.hasExtension(f1, ".z")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(f1, "z")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(f1, ".x")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(f1, "")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(f2, "")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(f2, ".z")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testHasExtensionURLString() {
+ assertTrue(FileSystem.hasExtension(u1, ".z")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(u1, "z")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u1, ".x")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u1, "")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(u2, "")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u2, ".z")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(u3, ".z")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(u3, "z")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u3, ".x")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u3, "")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(u7, ".z")); //$NON-NLS-1$
+ assertTrue(FileSystem.hasExtension(u7, "z")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u7, ".x")); //$NON-NLS-1$
+ assertFalse(FileSystem.hasExtension(u7, "")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testRemoveExtensionFile() {
+ assertEquals(new File("/home/test.x.z"), FileSystem.removeExtension(f1)); //$NON-NLS-1$
+ assertEquals(new File("/home"), FileSystem.removeExtension(f2)); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testRemoveExtensionURL() throws Exception {
+ assertEquals(new File("/home/test.x.z").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.removeExtension(u1));
+ assertEquals(new File("/home").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.removeExtension(u2));
+ assertEquals(u5, FileSystem.removeExtension(u3));
+ assertEquals(u9, FileSystem.removeExtension(u7));
+ }
+
+ /**
+ */
+ public void testReplaceExtensionFileString() {
+ assertEquals(new File("/home/test.x.z.toto"), FileSystem.replaceExtension(f1, ".toto")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals(new File("/home.toto"), FileSystem.replaceExtension(f2, ".toto")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testReplaceExtensionURLString() throws Exception {
+ assertEquals(new File("/home/test.x.z.toto").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.replaceExtension(u1, ".toto")); //$NON-NLS-1$
+ assertEquals(new File("/home.toto").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.replaceExtension(u2, ".toto")); //$NON-NLS-1$
+ assertEquals(u6, FileSystem.replaceExtension(u3, ".toto")); //$NON-NLS-1$
+ assertEquals(u10, FileSystem.replaceExtension(u7, ".toto")); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testConvertStringToUrl() throws Exception {
+ assertNull(FileSystem.convertStringToUrl(null, true));
+ assertNull(FileSystem.convertStringToUrl("", true)); //$NON-NLS-1$
+ assertNull(FileSystem.convertStringToUrl(null, false));
+ assertNull(FileSystem.convertStringToUrl("", false)); //$NON-NLS-1$
+
+ assertEquals(new URL("http://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("http://www.arakhne.org/", true)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("http://www.arakhne.org/", false)); //$NON-NLS-1$
+
+ assertEquals(new URL("file:"+f1.getAbsolutePath()), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("file:"+f1.getAbsolutePath(), true)); //$NON-NLS-1$
+ assertEquals(new URL("file:"+f1.getAbsolutePath()), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("file:"+f1.getAbsolutePath(), false)); //$NON-NLS-1$
+ assertEquals(new URL("file:./toto"), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("file:./toto", false)); //$NON-NLS-1$
+
+ assertEquals(new File("jar:/home/test/j.jar").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("jar:/home/test/j.jar", true)); //$NON-NLS-1$
+ assertEquals(new File("jar:/home/test/j.jar").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("jar:/home/test/j.jar", false)); //$NON-NLS-1$
+
+ assertEquals(new File("jar:/home/test/j.jar!/org/arakhne/vmutil/ff.properties").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("jar:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", true)); //$NON-NLS-1$
+ assertEquals(new File("jar:/home/test/j.jar!/org/arakhne/vmutil/ff.properties").toURI().toURL(), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("jar:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", false)); //$NON-NLS-1$
+
+ assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", true)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.convertStringToUrl("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", false)); //$NON-NLS-1$
+
+ URL testResource = Resources.getResource("/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(testResource);
+ URL testResourceFileRel = new File("org/arakhne/vmutil/test.txt").toURI().toURL(); //$NON-NLS-1$
+ URL testResourceFileAbs = new File("/org/arakhne/vmutil/test.txt").toURI().toURL(); //$NON-NLS-1$
+
+ assertEquals(testResource,
+ FileSystem.convertStringToUrl("resource:/org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+ assertEquals(null,
+ FileSystem.convertStringToUrl("resource:/org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+ assertEquals(testResource,
+ FileSystem.convertStringToUrl("resource:org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+ assertEquals(null,
+ FileSystem.convertStringToUrl("resource:org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+ assertEquals(testResource,
+ FileSystem.convertStringToUrl("/org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+ assertEquals(testResourceFileAbs,
+ FileSystem.convertStringToUrl("/org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+ assertEquals(testResource,
+ FileSystem.convertStringToUrl("org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+ assertEquals(testResourceFileRel,
+ FileSystem.convertStringToUrl("org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testConvertUrlToFile() throws Exception {
+ assertEquals(f1,
+ FileSystem.convertUrlToFile(new URL("file:"+f1.getAbsolutePath()))); //$NON-NLS-1$
+
+ try {
+ FileSystem.convertUrlToFile(new URL("http://www.arakhne.org")); //$NON-NLS-1$
+ fail("not a file URL"); //$NON-NLS-1$
+ }
+ catch(IllegalArgumentException _) {
+ //
+ }
+
+ assertEquals(new File("toto").getCanonicalPath(), //$NON-NLS-1$
+ FileSystem.convertUrlToFile(new URL("file:./toto")).getCanonicalPath()); //$NON-NLS-1$
+
+ assertEquals(new File("toto").getCanonicalPath(), //$NON-NLS-1$
+ FileSystem.convertUrlToFile(new URL("file:toto")).getCanonicalPath()); //$NON-NLS-1$
+
+ assertEquals(new File("toto").getCanonicalPath(), //$NON-NLS-1$
+ FileSystem.convertUrlToFile(new URL("file:./abs/../toto")).getCanonicalPath()); //$NON-NLS-1$
+
+ assertEquals(new File("/toto").getCanonicalPath(), //$NON-NLS-1$
+ FileSystem.convertUrlToFile(new URL("file:/toto")).getCanonicalPath()); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testMakeAbsoluteFileFile() {
+ File root = new File(File.separator+"myroot"); //$NON-NLS-1$
+
+ assertNull(FileSystem.makeAbsolute((File)null, null));
+ assertNull(FileSystem.makeAbsolute((File)null, root));
+
+ assertEquals(new File(File.separator+"toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new File(File.separator+"toto"), null)); //$NON-NLS-1$
+ assertEquals(new File("toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new File("toto"), null)); //$NON-NLS-1$
+
+ assertEquals(new File(File.separator+"toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new File(File.separator+"toto"), root)); //$NON-NLS-1$
+ assertEquals(new File(File.separator+"myroot"+File.separator+"toto"), //$NON-NLS-1$ //$NON-NLS-2$
+ FileSystem.makeAbsolute(new File("toto"), root)); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testMakeAbsoluteURLFile() throws Exception {
+ File root = new File(File.separator+"myroot"); //$NON-NLS-1$
+
+ assertNull(FileSystem.makeAbsolute((URL)null, (File)null));
+ assertNull(FileSystem.makeAbsolute((URL)null, root));
+
+ assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:/toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("file:toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("file:/myroot/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("http://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("https://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("https://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("https://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("https://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("ftp://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("ftp://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("ftp://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("ftp://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (File)null)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:/myroot/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testMakeAbsoluteURLURL() throws Exception {
+ URL root = new File(File.separator+"myroot").toURI().toURL(); //$NON-NLS-1$
+
+ assertNull(FileSystem.makeAbsolute((URL)null, (URL)null));
+ assertNull(FileSystem.makeAbsolute((URL)null, root));
+
+ assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:/toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("file:toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("file:/myroot/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("file:toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("http://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("http://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("https://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("https://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("https://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("https://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("ftp://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("ftp://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("ftp://www.arakhne.org/toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto"), root)); //$NON-NLS-1$
+ assertEquals(new URL("ftp://www.arakhne.org/./toto"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto"), root)); //$NON-NLS-1$
+
+ assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (URL)null)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+ assertEquals(new URL("jar:file:/myroot/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+ FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testGetParentURLURL() throws Exception {
+ assertEquals(
+ new URL("http://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("http://www.arakhne.org"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("http://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("http://www.arakhne.org/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("http://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("http://www.arakhne.org/toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("http://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("http://www.arakhne.org/toto/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("http://www.arakhne.org/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("http://www.arakhne.org/toto/titi"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("http://www.arakhne.org/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("http://www.arakhne.org/toto/titi/"))); //$NON-NLS-1$
+
+ assertEquals(
+ new URL("https://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("https://www.arakhne.org"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("https://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("https://www.arakhne.org/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("https://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("https://www.arakhne.org/toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("https://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("https://www.arakhne.org/toto/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("https://www.arakhne.org/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("https://www.arakhne.org/toto/titi"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("https://www.arakhne.org/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("https://www.arakhne.org/toto/titi/"))); //$NON-NLS-1$
+
+ assertEquals(
+ new URL("ftp://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("ftp://www.arakhne.org"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("ftp://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("ftp://www.arakhne.org/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("ftp://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("ftp://www.arakhne.org/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("ftp://www.arakhne.org/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto/titi"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("ftp://www.arakhne.org/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto/titi/"))); //$NON-NLS-1$
+
+ assertEquals(
+ new URL("file:/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:/toto/titi"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:/toto/titi/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:/toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:/toto/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:./toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:./toto/titi"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:./toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:./toto/titi/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:./"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:./toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:./"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:./toto/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:../"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:."))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:../"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:./"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:../"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("file:../"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("file:toto/"))); //$NON-NLS-1$
+
+ assertEquals(
+ new URL("jar:file:test.jar!/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("jar:file:test.jar!/toto/titi"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("jar:file:test.jar!/toto/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("jar:file:test.jar!/toto/titi/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("jar:file:test.jar!/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("jar:file:test.jar!/toto"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("jar:file:test.jar!/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("jar:file:test.jar!/toto/"))); //$NON-NLS-1$
+ assertEquals(
+ new URL("jar:file:test.jar!/"), //$NON-NLS-1$
+ FileSystem.getParentURL(new URL("jar:file:test.jar!/"))); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,144 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collections;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class FileURLConnectionTest extends TestCase {
+
+ private FileURLConnection connection;
+
+ static {
+ URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ URL resourceUrl = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(resourceUrl);
+ this.connection = new FileURLConnection(resourceUrl);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void tearDown() throws Exception {
+ this.connection = null;
+ super.tearDown();
+ }
+
+ /**
+ */
+ public void testGetHeaderFieldKeyInt() {
+ assertEquals("content-type", this.connection.getHeaderFieldKey(0)); //$NON-NLS-1$
+ assertEquals("content-length", this.connection.getHeaderFieldKey(1)); //$NON-NLS-1$
+ assertEquals("last-modified", this.connection.getHeaderFieldKey(2)); //$NON-NLS-1$
+ assertNull(this.connection.getHeaderFieldKey(3));
+ }
+
+ /**
+ */
+ public void testGetHeaderFieldInt() {
+ assertEquals("text/plain", this.connection.getHeaderField(0)); //$NON-NLS-1$
+ assertEquals("19", this.connection.getHeaderField(1)); //$NON-NLS-1$
+ assertNotNull(this.connection.getHeaderField(2));
+ assertNull(this.connection.getHeaderField(3));
+ }
+
+ /**
+ */
+ public void testGetHeaderFieldString() {
+ assertEquals("text/plain", this.connection.getHeaderField("content-type")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("19", this.connection.getHeaderField("content-length")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertNotNull(this.connection.getHeaderField("last-modified")); //$NON-NLS-1$
+ assertNull(this.connection.getHeaderField("expires")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public void testGetHeaderFields() {
+ Map<?,?> map = this.connection.getHeaderFields();
+ assertNotNull(map);
+ assertEquals(3, map.size());
+ assertEquals(Collections.singletonList("text/plain"), map.get("content-type")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals(Collections.singletonList("19"), map.get("content-length")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertNotNull(map.get("last-modified")); //$NON-NLS-1$
+ assertNull(map.get("expires")); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws IOException
+ */
+ public void testGetInputStream() throws IOException {
+ InputStream is = this.connection.getInputStream();
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line = br.readLine();
+ br.close();
+ assertEquals("FOR UNIT TEST ONLY ", line); //$NON-NLS-1$
+ }
+
+ /**
+ * @throws IOException
+ */
+ public void testGetOutputStream() throws IOException {
+ File tmpFile = File.createTempFile("unittest", ".txt"); //$NON-NLS-1$ //$NON-NLS-2$
+ tmpFile.deleteOnExit();
+
+ URLConnection con = new FileURLConnection(tmpFile.toURI().toURL());
+ con.setDoOutput(true);
+
+ OutputStream os = con.getOutputStream();
+ BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
+ bw.write("HELLO WORLD!"); //$NON-NLS-1$
+ bw.close();
+
+ assertEquals(12, tmpFile.length());
+
+ BufferedReader br = new BufferedReader(new FileReader(tmpFile));
+ String line = br.readLine();
+ br.close();
+ assertEquals("HELLO WORLD!", line); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourceURLConnectionTest.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourceURLConnectionTest.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourceURLConnectionTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name$ $Revision$ $Date$
+ */
+public class ResourceURLConnectionTest extends TestCase {
+
+ private ResourceURLConnection connection;
+
+ static {
+ URL.setURLStreamHandlerFactory(new ResourceURLStreamHandlerFactory());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ URL resourceUrl = new URL("resource:org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(resourceUrl);
+ this.connection = new ResourceURLConnection(resourceUrl);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void tearDown() throws Exception {
+ this.connection = null;
+ super.tearDown();
+ }
+
+ /**
+ * @throws IOException
+ */
+ public void testGetInputStream() throws IOException {
+ InputStream is = this.connection.getInputStream();
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line = br.readLine();
+ br.close();
+ assertEquals("FOR UNIT TEST ONLY ", line); //$NON-NLS-1$
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourcesTest.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourcesTest.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/ResourcesTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,99 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+/**
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public class ResourcesTest extends TestCase {
+
+ /**
+ */
+ public void testGetResourceString() {
+ URL u1 = Resources.getResource("/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(u1);
+
+ URL u2 = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(u2);
+
+ assertEquals(u1,u2);
+ }
+
+ /**
+ */
+ public void testGetResourceClassString() {
+ URL u1 = Resources.getResource(ResourcesTest.class, "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(u1);
+
+ URL u2 = Resources.getResource(ResourcesTest.class, "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(u2);
+
+ assertEquals(u1,u2);
+ }
+
+ /**
+ */
+ public void testGetResourceClassLoaderString() {
+ URL u1 = Resources.getResource(ResourcesTest.class.getClassLoader(), "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(u1);
+
+ URL u2 = Resources.getResource(ResourcesTest.class.getClassLoader(), "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(u2);
+
+ assertEquals(u1,u2);
+ }
+
+ /**
+ */
+ public void testGetResourceAsStreamString() {
+ InputStream is = Resources.getResourceAsStream("/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(is);
+
+ is = Resources.getResourceAsStream("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(is);
+ }
+
+ /**
+ */
+ public void testGetResourceAsStreamClassString() {
+ InputStream is = Resources.getResourceAsStream(ResourcesTest.class, "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(is);
+
+ is = Resources.getResourceAsStream(ResourcesTest.class, "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(is);
+ }
+
+ /**
+ */
+ public void testGetResourceAsStreamClassLoaderString() {
+ InputStream is = Resources.getResourceAsStream(ResourcesTest.class.getClassLoader(), "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(is);
+
+ is = Resources.getResourceAsStream(ResourcesTest.class.getClassLoader(), "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+ assertNotNull(is);
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,294 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+* @version $Name$ $Revision$ $Date$
+*/
+public class VMCommandLineTest extends TestCase {
+
+ private static final String[] commandLine = new String[] {
+ "-D=true", "-v", "clean", "-v", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "-F", "-b", "-v", "package", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "-F", "123", "-nob", "installters", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "-S", "-b", "--", "-v"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+
+ private static final String[] commandLine2 = new String[] {"-D=true"}; //$NON-NLS-1$
+
+ private static final String[] optionDefinitions = new String[] {
+ "D=b", "S=s", "F:f", "v+", "b!"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ VMCommandLine.saveVMParameters(null, new String[0]);
+ }
+
+ /**
+ */
+ public final void testSaveVMParameters() {
+ assertTrue(Arrays.equals(new String[0], VMCommandLine.getCommandLineParameters()));
+ VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+ assertTrue(Arrays.equals(commandLine, VMCommandLine.getCommandLineParameters()));
+ VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine2);
+ assertTrue(Arrays.equals(commandLine2, VMCommandLine.getCommandLineParameters()));
+ }
+
+ /**
+ */
+ public final void testSaveVMParametersIfNotSet() {
+ assertTrue(Arrays.equals(new String[0], VMCommandLine.getCommandLineParameters()));
+ VMCommandLine.saveVMParametersIfNotSet(VMCommandLineTest.class, commandLine);
+ assertTrue(Arrays.equals(commandLine, VMCommandLine.getCommandLineParameters()));
+ VMCommandLine.saveVMParametersIfNotSet(VMCommandLineTest.class, commandLine2);
+ assertTrue(Arrays.equals(commandLine, VMCommandLine.getCommandLineParameters()));
+ }
+
+ /**
+ */
+ public final void testShiftCommandLineParameters() {
+ VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+ assertEquals("-D=true", VMCommandLine.shiftCommandLineParameters()); //$NON-NLS-1$
+ assertTrue(Arrays.equals(new String[] {
+ "-v", "clean", "-v", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ "-F", "-b", "-v", "package", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "-F", "123", "-nob", "installters", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "-S", "-b", "--", "-v"}, //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ VMCommandLine.getCommandLineParameters()));
+ }
+
+ /**
+ */
+ public final void testGetCommandLineOptions() {
+ assertEquals(Collections.emptyMap(), VMCommandLine.getCommandLineOptions());
+ }
+
+ /**
+ */
+ public final void testSplitOptionsAndParameters() {
+ VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+ VMCommandLine.splitOptionsAndParameters(optionDefinitions);
+
+ Map<String,List<Object>> options = VMCommandLine.getCommandLineOptions();
+ String[] parameters = VMCommandLine.getCommandLineParameters();
+ List<Object> values;
+
+ assertNotNull(options);
+ assertEquals(5, options.size());
+
+ assertTrue(options.containsKey("D")); //$NON-NLS-1$
+ values = options.get("D"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals(true, values.get(0));
+
+ assertTrue(options.containsKey("v")); //$NON-NLS-1$
+ values = options.get("v"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals((long)3, values.get(0));
+
+ assertTrue(options.containsKey("F")); //$NON-NLS-1$
+ values = options.get("F"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(2, values.size());
+ assertEquals(0., values.get(0));
+ assertEquals(123., values.get(1));
+
+ assertTrue(options.containsKey("b")); //$NON-NLS-1$
+ values = options.get("b"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals(false, values.get(0));
+
+ assertTrue(options.containsKey("S")); //$NON-NLS-1$
+ values = options.get("S"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals("-b", values.get(0)); //$NON-NLS-1$
+
+ values = options.get("nob"); //$NON-NLS-1$
+ assertNull(values);
+
+ assertNotNull(parameters);
+ assertEquals(4, parameters.length);
+ assertEquals("clean", parameters[0]); //$NON-NLS-1$
+ assertEquals("package", parameters[1]); //$NON-NLS-1$
+ assertEquals("installters", parameters[2]); //$NON-NLS-1$
+ assertEquals("-v", parameters[3]); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testGetCommandLineOption() {
+ assertNull(VMCommandLine.getCommandLineOption("S")); //$NON-NLS-1$
+
+ VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+ VMCommandLine.splitOptionsAndParameters(optionDefinitions);
+
+ List<Object> values;
+ values = VMCommandLine.getCommandLineOption("S"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals("-b", values.get(0)); //$NON-NLS-1$
+
+ assertNull(VMCommandLine.getCommandLineOption("nob")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testHasCommandLineOption() {
+ assertFalse(VMCommandLine.hasCommandLineOption("S")); //$NON-NLS-1$
+
+ VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+ VMCommandLine.splitOptionsAndParameters(optionDefinitions);
+
+ assertTrue(VMCommandLine.hasCommandLineOption("S")); //$NON-NLS-1$
+ assertFalse(VMCommandLine.hasCommandLineOption("nob")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testVMCommandLineClassOfQStringArray() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, commandLine);
+ assertTrue(Arrays.equals(commandLine, c.getParameters()));
+ }
+
+ /**
+ */
+ public final void testVMCommandLineClassOfQStringArrayStringArray() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertTrue(Arrays.equals(new String[] {
+ "clean", "package", "installters", "-v" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ }, c.getParameters()));
+ }
+
+ /**
+ */
+ public final void testHasOption() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertTrue(c.hasOption("S")); //$NON-NLS-1$
+ assertTrue(c.hasOption("b")); //$NON-NLS-1$
+ assertFalse(c.hasOption("nob")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testGetFirstOptionValue() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertEquals("-b", c.getFirstOptionValue("S")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals(false, c.getFirstOptionValue("b")); //$NON-NLS-1$
+ assertEquals(0., c.getFirstOptionValue("F")); //$NON-NLS-1$
+ assertNull(c.getFirstOptionValue("nob")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testGetOptionValues() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ List<Object> values;
+
+ values = c.getOptionValues("D"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals(true, values.get(0));
+
+ values = c.getOptionValues("v"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals((long)3, values.get(0));
+
+ values = c.getOptionValues("F"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(2, values.size());
+ assertEquals(0., values.get(0));
+ assertEquals(123., values.get(1));
+
+ values = c.getOptionValues("b"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals(false, values.get(0));
+
+ values = c.getOptionValues("S"); //$NON-NLS-1$
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals("-b", values.get(0)); //$NON-NLS-1$
+
+ assertNull(c.getOptionValues("nob")); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testGetParameters() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertNotSame(commandLine, c.getParameters());
+ assertTrue(Arrays.equals(new String[] {
+ "clean", "package", "installters", "-v" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ }, c.getParameters()));
+ }
+
+ /**
+ */
+ public final void testShiftParameters() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertEquals("clean", c.shiftParameters()); //$NON-NLS-1$
+ assertNotSame(commandLine, c.getParameters());
+ assertTrue(Arrays.equals(new String[] {
+ "package", "installters", "-v" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }, c.getParameters()));
+ }
+
+ /**
+ */
+ public final void testGetParameterCount() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertEquals(4, c.getParameterCount());
+ }
+
+ /**
+ */
+ public final void testGetParameterAt() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertEquals("clean", c.getParameterAt(0)); //$NON-NLS-1$
+ assertEquals("package", c.getParameterAt(1)); //$NON-NLS-1$
+ assertEquals("installters", c.getParameterAt(2)); //$NON-NLS-1$
+ assertEquals("-v", c.getParameterAt(3)); //$NON-NLS-1$
+ }
+
+ /**
+ */
+ public final void testIsParameterExists() {
+ VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+ assertTrue(c.isParameterExists(0));
+ assertTrue(c.isParameterExists(1));
+ assertTrue(c.isParameterExists(2));
+ assertTrue(c.isParameterExists(3));
+ assertFalse(c.isParameterExists(5));
+ }
+
+}
Added: tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/arakhne/vmutil/test.txt
===================================================================
--- tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/arakhne/vmutil/test.txt (rev 0)
+++ tags/afc-2.0/arakhneVmutils/java/src/test/resources/org/arakhne/vmutil/test.txt 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1 @@
+FOR UNIT TEST ONLY
\ No newline at end of file
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/linux32/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/linux32/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/linux32/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>josuuid</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>4.2</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>josuuid-linux32</artifactId>
+ <packaging>so</packaging>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneVmutils-java</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${artifactId}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>native-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <compilerProvider>generic</compilerProvider>
+ <compilerStartOptions>
+ <compilerStartOption>-m32 -O3 -Wall -Werror -fmessage-length=0</compilerStartOption>
+ </compilerStartOptions>
+
+ <javahOS>linux</javahOS>
+
+ <sources>
+ <source>
+ <directory>../src/main/native</directory>
+ <fileNames>
+ <fileName>josuuid.cpp</fileName>
+ <fileName>OperatingSystemJNI.cpp</fileName>
+ </fileNames>
+ </source>
+
+ </sources>
+
+ <linkerStartOptions>
+ <linkerStartOption>-m32 -shared -lstdc++</linkerStartOption>
+ </linkerStartOptions>
+
+ </configuration>
+
+ <executions>
+ <execution>
+ <id>javah</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <classNames>
+ <className>org.arakhne.vmutil.OperatingSystem</className>
+ </classNames>
+ </configuration>
+ <goals>
+ <goal>javah</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ <environmentVariables>
+ <LD_LIBRARY_PATH>${project.build.directory}</LD_LIBRARY_PATH>
+ </environmentVariables>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+
+</project>
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/linux64/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/linux64/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/linux64/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>josuuid</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>4.2</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>josuuid-linux64</artifactId>
+ <packaging>so</packaging>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneVmutils-java</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${artifactId}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>native-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <compilerProvider>generic</compilerProvider>
+ <compilerStartOptions>
+ <compilerStartOption>-m64 -fPIC -O3 -Wall -Werror -fmessage-length=0</compilerStartOption>
+ </compilerStartOptions>
+
+ <javahOS>linux</javahOS>
+
+ <sources>
+ <source>
+ <directory>../src/main/native</directory>
+ <fileNames>
+ <fileName>josuuid.cpp</fileName>
+ <fileName>OperatingSystemJNI.cpp</fileName>
+ </fileNames>
+ </source>
+
+ </sources>
+
+ <linkerStartOptions>
+ <linkerStartOption>-m64 -shared -lstdc++</linkerStartOption>
+ </linkerStartOptions>
+
+ </configuration>
+
+ <executions>
+ <execution>
+ <id>javah</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <classNames>
+ <className>org.arakhne.vmutil.OperatingSystem</className>
+ </classNames>
+ </configuration>
+ <goals>
+ <goal>javah</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ <environmentVariables>
+ <LD_LIBRARY_PATH>${project.build.directory}</LD_LIBRARY_PATH>
+ </environmentVariables>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+
+</project>
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/mingw/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/mingw/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/mingw/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>josuuid</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>4.2</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>josuuid-mingw</artifactId>
+ <packaging>dll</packaging>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneVmutils-java</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${artifactId}</finalName>
+
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>enforce-beanshell</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <evaluateBeanshell>
+ <condition>
+ String path = System.getenv("PATH");
+ String[] parts = path.split(File.pathSeparator);
+ boolean ok = false;
+ for(int i=0; !ok && i<parts.length; i++) {
+ ok = new File(parts[i],"i586-mingw32msvc-g++").canExecute();
+ }
+ ok
+ </condition>
+ </evaluateBeanshell>
+ <requireOS>
+ <name>linux</name>
+ <family>unix</family>
+ </requireOS>
+ </rules>
+ <fail>true</fail>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>native-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <compilerProvider>generic</compilerProvider>
+ <compilerExecutable>i586-mingw32msvc-g++</compilerExecutable>
+ <compilerStartOptions>
+ <compilerStartOption>-O0 -Wall -Werror -fmessage-length=0</compilerStartOption>
+ </compilerStartOptions>
+
+ <javahOS>linux</javahOS> <!-- not 'windows' to retreive the jni_md.h file -->
+
+ <sources>
+ <source>
+ <directory>../src/main/native</directory>
+ <fileNames>
+ <fileName>josuuid.cpp</fileName>
+ <fileName>winos.cpp</fileName>
+ <fileName>OperatingSystemJNI.cpp</fileName>
+ </fileNames>
+ </source>
+ </sources>
+
+ <linkerExecutable>i586-mingw32msvc-g++</linkerExecutable>
+ <linkerStartOptions>
+ <linkerStartOption>-shared</linkerStartOption>
+ </linkerStartOptions>
+
+ </configuration>
+
+ <executions>
+ <execution>
+ <id>javah</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <classNames>
+ <className>org.arakhne.vmutil.OperatingSystem</className>
+ </classNames>
+ </configuration>
+ <goals>
+ <goal>javah</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ <environmentVariables>
+ <LD_LIBRARY_PATH>${project.build.directory}</LD_LIBRARY_PATH>
+ </environmentVariables>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+
+</project>
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>arakhneVmutils-native</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>4.2</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>josuuid</artifactId>
+ <packaging>pom</packaging>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <profiles>
+
+ <profile>
+ <id>linux-hosted</id>
+ <activation>
+ <os>
+ <name>linux</name>
+ <family>unix</family>
+ </os>
+ </activation>
+ <modules>
+ <module>linux32</module>
+ <module>linux64</module>
+ <module>mingw</module>
+ </modules>
+ </profile>
+
+ <!--profile>
+ <id>win32</id>
+ <activation>
+ <os>
+ <name>Windows®</name>
+ <family>Windows</family>
+ <arch>x86</arch>
+ <version>5.1.2600</version>
+ </os>
+ </activation>
+ <modules>
+ <module>win32</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>macosx</id>
+ <activation>
+ <property>
+ <name>platform</name>
+ <value>macosx</value>
+ </property>
+ </activation>
+ <modules>
+ <module>macosx</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>aix</id>
+ <activation>
+ <property>
+ <name>platform</name>
+ <value>aix</value>
+ </property>
+ </activation>
+ <modules>
+ <module>aix</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>solaris</id>
+ <activation>
+ <property>
+ <name>platform</name>
+ <value>solaris</value>
+ </property>
+ </activation>
+ <modules>
+ <module>solaris</module>
+ </modules>
+ </profile-->
+
+ </profiles>
+
+</project>
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/OperatingSystemJNI.cpp
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/OperatingSystemJNI.cpp (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/OperatingSystemJNI.cpp 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2008 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+#ifdef DEBUG
+# warning THE LIBRARY IS COMPILED WITH DEBUG INFORMATION
+#endif
+
+#include <jni.h>
+#include <stdlib.h>
+
+#include "org_arakhne_vmutil_OperatingSystem.h"
+#include "josuuid.h"
+
+/*
+ * Class: org_arakhne_vmutil_OperatingSystem
+ * Method: getOSSerialNumber
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_org_arakhne_vmutil_OperatingSystem_getOSSerialNumber
+(JNIEnv * env, jclass clazz) {
+ jstring jSerial = NULL;
+ char* cSerial = getOSSerial();
+ if (cSerial!=NULL) {
+ jSerial = env->NewStringUTF (cSerial);
+ free(cSerial);
+ }
+ return jSerial;
+}
+
+
+/*
+ * Class: org_arakhne_vmutil_OperatingSystem
+ * Method: getOSUUID
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_org_arakhne_vmutil_OperatingSystem_getOSUUID
+(JNIEnv *env, jclass clazz) {
+ jstring jUUID = NULL;
+ char* cUUID = getOSUUID();
+ if (cUUID!=NULL) {
+ jUUID = env->NewStringUTF (cUUID);
+ free(cUUID);
+ }
+ return jUUID;
+}
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.cpp
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.cpp (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.cpp 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,193 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2008 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+#ifdef DEBUG
+# warning THE LIBRARY IS COMPILED WITH DEBUG INFORMATION
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "osmacro.h"
+
+#ifdef __WINDOWS__
+# include <windows.h>
+# include "winos.h"
+# define WINUUID_PART_COUNT 4
+static char hexCharacters[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+#else
+# include <unistd.h>
+# define DWORD unsigned long int
+#endif
+
+#include "josuuid.h"
+
+/* Remove white spaces at the begining and at the end of a string */
+static void trim(char** text) {
+ char* t;
+ unsigned long startIdx, endIdx;
+ unsigned long len, i;
+ if ((text==NULL)||(*text==NULL)) return;
+ len = strlen(*text);
+ // Search starting character
+ for(startIdx=0; startIdx<len; startIdx++) {
+ if (!isspace((*text)[startIdx])) break;
+ }
+ if (startIdx>=len) {
+ free(*text);
+ *text = strdup("");
+ return;
+ }
+ // Search ending character
+ for(endIdx=len-1; endIdx>=0; endIdx--) {
+ if (!isspace((*text)[endIdx])) break;
+ }
+ if (endIdx<0) {
+ free(*text);
+ *text = strdup("");
+ return;
+ }
+ // Create the new string
+ t = (char*)malloc(sizeof(char)*(endIdx-startIdx+2));
+ for(i=0; startIdx<=endIdx; i++, startIdx++) {
+ t[i] = (*text)[startIdx];
+ }
+ t[i] = '\0';
+ free(*text);
+ *text = t;
+}
+
+#ifndef __WINDOWS__
+/* Run the specified shell command and replies its standard output */
+static char* runCommand(const char* cmd) {
+ FILE* cmdOutput;
+ char* result = NULL;
+
+ cmdOutput = popen(cmd, "r");
+
+ if (cmdOutput!=NULL) {
+ char buffer[128];
+ unsigned long i,j, count = 0;
+ unsigned long charCount;
+
+ charCount = fread(buffer, sizeof(char), 128, cmdOutput);
+ while (charCount>0) {
+ result = (char*)realloc(result,sizeof(char)*(count+charCount+1));
+ for(i=0, j=count; i<charCount; i++, j++) {
+ result[j] = buffer[i];
+ }
+ count += charCount;
+ result[count] = '\0';
+ charCount = fread(buffer, sizeof(char), 128, cmdOutput);
+ }
+
+ pclose(cmdOutput);
+ }
+
+ return result;
+}
+#endif
+
+/* Replies the serial number of the system */
+char* getOSSerial() {
+#ifdef __WINDOWS__
+ DWORD size = 0;
+ BYTE* data = NULL;
+ if (getWindowsSerial(&data, &size)) {
+ char* serial = new char[size];
+ for(unsigned long i=0; i<size; i++) {
+ serial[i] = data[i];
+ }
+ free(data);
+ trim(&serial);
+ return serial;
+ }
+ return NULL;
+#else
+ char* result = runCommand("hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.serial");
+ if (result!=NULL) {
+ trim(&result);
+ }
+ else {
+ result = runCommand("hal-get-property --udi /org/freedesktop/Hal/devices/computer --key smbios.system.serial");
+ if (result!=NULL) {
+ trim(&result);
+ }
+ }
+ return result;
+#endif
+}
+
+/* Replies the UUID of the system */
+char* getOSUUID() {
+#ifdef __WINDOWS__
+ DWORD size;
+ BYTE* data;
+ if (getWindowsSerial(&data, &size)) {
+ unsigned long i, j, k, totalSize = 2*(size-1);
+ char* serial = (char*)malloc(sizeof(char)*(totalSize+(totalSize/WINUUID_PART_COUNT)+2));
+ char characterToTreat;
+ short b0, b1;
+ bool lastIsSeparator = false;
+
+ for(i=0, j=0, k=WINUUID_PART_COUNT; i<size; i++) {
+ characterToTreat = data[i];
+ if (isalnum(characterToTreat)) {
+ b0 = (characterToTreat & 0x0F) ^ 0x0F;
+ b1 = ((characterToTreat & 0xF0) >> 4) ^ 0x0F;
+ serial[j++] = hexCharacters[b0];
+ serial[j++] = hexCharacters[b1];
+ k --;
+ if (k<=0) {
+ serial[j++] = '-';
+ k = WINUUID_PART_COUNT;
+ lastIsSeparator = true;
+ }
+ else {
+ lastIsSeparator = false;
+ }
+ }
+ }
+ if (lastIsSeparator) j--;
+ serial[j] = '\0';
+ free(data);
+
+ trim(&serial);
+
+ return serial;
+ }
+ return NULL;
+#else
+ char* result = runCommand("hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid");
+ if (result!=NULL) {
+ trim(&result);
+ }
+ else {
+ result = runCommand("hal-get-property --udi /org/freedesktop/Hal/devices/computer --key smbios.system.uuid");
+ if (result!=NULL) {
+ trim(&result);
+ }
+ }
+ return result;
+#endif
+}
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.h
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.h (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/josuuid.h 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+#ifndef __JOSUUID_H__
+# define __JOSUUID_H__
+
+# include "osmacro.h"
+
+/* Replies the serial number of the system */
+char* getOSSerial();
+
+/* Replies the UUID of the system */
+char* getOSUUID();
+
+#endif /* __JOSUUID_H__ */
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/osmacro.h
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/osmacro.h (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/osmacro.h 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+#ifndef __OSMACRO_H__
+# define __OSMACRO_H__
+
+# if defined(WINDOWS) || defined(WIN32) || defined(WIN64) || defined(WINNT)
+# define __WINDOWS__
+# undef __UNIX__
+# else
+# define __UNIX__
+# undef __WINDOWS__
+# endif
+
+#endif /* __OSMACRO_H__ */
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.cpp
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.cpp (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.cpp 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,178 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+#include "osmacro.h"
+
+#ifdef DEBUG
+# warning THE LIBRARY IS COMPILED WITH DEBUG INFORMATION
+#endif
+
+#ifndef __WINDOWS__
+# error You may use Windows compiler
+#endif
+
+#include <windows.h>
+#include <winreg.h>
+#include "winos.h"
+
+#include <stdio.h>
+
+/* Replies the windows version */
+BOOL getWindowsVersion(DWORD *version) {
+ OSVERSIONINFO osinfo;
+ osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if (!GetVersionEx(&osinfo))
+ return false;
+
+ DWORD platform_id = osinfo.dwPlatformId;
+ DWORD minor_version = osinfo.dwMinorVersion;
+ DWORD major_version = osinfo.dwMajorVersion;
+ DWORD build_number = osinfo.dwBuildNumber & 0xFFFF; // Win 95 needs this
+
+ if ((platform_id == VER_PLATFORM_WIN32_WINDOWS) && (major_version == 4)) {
+ if ((minor_version < 10) && (build_number == 950))
+ *version = W95;
+ else if ((minor_version < 10) &&
+ ((build_number > 950) && (build_number <= 1080)))
+ *version = W95SP1;
+ else if ((minor_version < 10) && (build_number > 1080))
+ *version = W95OSR2;
+ else if ((minor_version == 10) && (build_number == 1998))
+ *version = W98;
+ else if ((minor_version == 10) &&
+ ((build_number > 1998) && (build_number < 2183)))
+ *version = W98SP1;
+ else if ((minor_version == 10) && (build_number >= 2183))
+ *version = W98SE;
+ else if (minor_version == 90)
+ *version = WME;
+ }
+ else if (platform_id == VER_PLATFORM_WIN32_NT) {
+ if ((major_version == 3) && (minor_version == 51))
+ *version = WNT351;
+ else if ((major_version == 4) && (minor_version == 0))
+ *version = WNT4;
+ else if ((major_version == 5) && (minor_version == 0))
+ *version = W2K;
+ else if ((major_version == 5) && (minor_version == 1))
+ *version = WXP;
+ }
+ else if (platform_id == VER_PLATFORM_WIN32_CE) {
+ *version = WCE;
+ }
+
+ return true;
+}
+
+/* Read the value of a registrery value */
+BOOL readRegistry(const CHAR* key, const CHAR* valueName, BYTE** data, DWORD* size) {
+ return readRegistryI(key,valueName,data,size,1);
+}
+
+/* Read the value of a registrery value */
+BOOL readRegistryI(const CHAR* key, const CHAR* valueName, BYTE** data, DWORD* size, BYTE allocationFactor) {
+ HKEY hKey = NULL; // registry handle, kept open between calls
+ LONG ret;
+
+ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS /*KEY_QUERY_VALUE*/, &hKey);
+ if (ret != ERROR_SUCCESS) return false;
+
+ // Get the size of the value
+ DWORD valueSize=0;
+ ret = RegQueryValueEx(
+ hKey,
+ valueName,
+ NULL, //reserved
+ NULL, //type
+ NULL, //data
+ &valueSize);
+ if (ret != ERROR_SUCCESS) return false;
+ if (size!=NULL) {
+ *size = valueSize;
+ }
+ // Read the value data
+ BYTE* valueData;
+
+ if (data!=NULL) {
+ DWORD valueType;
+ valueData = (BYTE*)malloc(sizeof(BYTE)*valueSize*allocationFactor);
+ ret = RegQueryValueEx(
+ hKey,
+ valueName,
+ NULL, //reserved
+ &valueType, //type
+ valueData,
+ &valueSize);
+ RegCloseKey(hKey);
+ if (ret != ERROR_SUCCESS) {
+ free(valueData);
+ return false;
+ }
+ *data = valueData;
+ }
+ else {
+ RegCloseKey(hKey);
+ }
+
+ return true;
+}
+
+/* Replies the serial number of the system */
+BOOL getWindowsSerial(BYTE** serial, DWORD* serialSize) {
+ return getWindowsSerialI(serial, serialSize, 1);
+}
+
+/* Replies the serial number of the system */
+BOOL getWindowsSerialI(BYTE** serial, DWORD* serialSize, BYTE allocationFactor) {
+ DWORD version;
+ getWindowsVersion(&version);
+
+ CHAR* reg_path;
+ if ((version >=WNT_FIRST) && (version <= WNT_LAST))
+ reg_path = (CHAR*)("Software\\Microsoft\\Windows NT\\CurrentVersion");
+ else
+ reg_path = (CHAR*)("Software\\Microsoft\\Windows\\CurrentVersion");
+
+ DWORD size = 0;
+ BYTE* data = NULL;
+ if (!readRegistryI(reg_path, "ProductId", &data, &size, allocationFactor)) {
+ if ((version >=WNT_FIRST) && (version <= WNT_LAST)) {
+ reg_path = (CHAR*)("Software\\Microsoft\\Windows\\CurrentVersion");
+ if (!readRegistryI(reg_path, "ProductId", &data, &size, allocationFactor))
+ return false;
+ }
+ else return false;
+ }
+
+ if (serial!=NULL) {
+ *serial = data;
+ }
+ else {
+ free(data);
+ }
+
+ if (serialSize!=NULL) {
+ *serialSize = size;
+ }
+
+ return true;
+}
Added: tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.h
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.h (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/josuuid/src/main/native/winos.h 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stéphane GALLAND
+ *
+ * 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
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+#ifndef __WINOS_H__
+# define __WINOS_H__
+
+# include "osmacro.h"
+
+# define W9XFIRST 1
+# define W95 1
+# define W95SP1 2
+# define W95OSR2 3
+# define W98 4
+# define W98SP1 5
+# define W98SE 6
+# define WME 7
+# define W9XLAST 99
+
+# define WNT_FIRST 101
+# define WNT351 101
+# define WNT4 102
+# define W2K 103
+# define WXP 104
+# define WNT_LAST 199
+
+# define WCEFIRST 201
+# define WCE 201
+# define WCELAST 299
+
+# ifndef VER_PLATFORM_WIN32_WINDOWS
+# define VER_PLATFORM_WIN32_WINDOWS 1
+# endif
+# ifndef VER_PLATFORM_WIN32_NT
+# define VER_PLATFORM_WIN32_NT 2
+# endif
+# ifndef VER_PLATFORM_WIN32_CE
+# define VER_PLATFORM_WIN32_CE 3
+# endif
+
+# include <windows.h>
+
+/* Replies the windows version */
+BOOL getWindowsVersion(DWORD *version);
+
+/* Read the value of a registrery value */
+BOOL readRegistry(const CHAR* key, const CHAR* valueName, BYTE** data, DWORD* size);
+
+/* Read the value of a registrery value */
+BOOL readRegistryI(const CHAR* key, const CHAR* valueName, BYTE** data, DWORD* size, BYTE allocationFactor);
+
+/* Replies the serial number of the system */
+BOOL getWindowsSerial(BYTE** serial, DWORD* serialSize);
+
+/* Replies the serial number of the system */
+BOOL getWindowsSerialI(BYTE** serial, DWORD* serialSize, BYTE allocationFactor);
+
+#endif
Added: tags/afc-2.0/arakhneVmutils/native/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/native/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/native/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>afc</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>2.0</version>
+ </parent>
+
+ <artifactId>arakhneVmutils-native</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <packaging>pom</packaging>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <modules>
+ <module>josuuid</module>
+ </modules>
+
+</project>
Added: tags/afc-2.0/arakhneVmutils/pom.xml
===================================================================
--- tags/afc-2.0/arakhneVmutils/pom.xml (rev 0)
+++ tags/afc-2.0/arakhneVmutils/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>afc</artifactId>
+ <groupId>org.arakhne.afc</groupId>
+ <version>2.0</version>
+ </parent>
+
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>arakhneVmutils</artifactId>
+ <packaging>pom</packaging>
+ <version>4.2</version>
+ <name>${pom.artifactId}</name>
+ <url>http://www.arakhne.org/arakhneVmutils/</url>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <!-- The modules have not this pom as parent
+ to avoid cyclic compilation problems -->
+ <modules>
+ <module>java</module>
+ <module>native</module>
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>bin.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attached</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: tags/afc-2.0/pom.xml
===================================================================
--- tags/afc-2.0/pom.xml (rev 0)
+++ tags/afc-2.0/pom.xml 2010-01-21 08:29:52 UTC (rev 117)
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.arakhne.afc</groupId>
+ <artifactId>afc</artifactId>
+ <packaging>pom</packaging>
+ <version>2.0</version>
+ <name>Arakhnê Foundation Classes</name>
+ <inceptionYear>2007</inceptionYear>
+ <url>http://www.arakhne.org/</url>
+ <description>Java library that provides additional tools.</description>
+
+
+ <!-- ======================================= -->
+ <!-- ==== Dependencies === -->
+ <!-- ======================================= -->
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <!-- ======================================= -->
+ <!-- ==== Project Information === -->
+ <!-- ======================================= -->
+
+ <modules>
+ <module>arakhneLogger</module>
+ <module>arakhneRefs</module>
+ <module>arakhneVmutils</module>
+ <module>arakhneLog4J</module>
+ </modules>
+
+ <licenses>
+ <license>
+ <name>GNU Lesser General Public License v2.0</name>
+ <url>http://www.gnu.org/licenses/lgpl.html</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <mailingLists>
+ <mailingList>
+ <name>dev@xxxxxxxxxxx</name>
+ <subscribe>mailto:dev-request@xxxxxxxxxxx</subscribe>
+ <unsubscribe>mailto:dev-request@xxxxxxxxxxx</unsubscribe>
+ <post>mailto:dev@xxxxxxxxxxx</post>
+ </mailingList>
+ </mailingLists>
+
+ <!-- ======================================= -->
+ <!-- ==== Organization Information === -->
+ <!-- ======================================= -->
+
+ <organization>
+ <name>Arakhnê.org Project</name>
+ <url>http://www.arakhne.org</url>
+ </organization>
+
+ <developers>
+ <developer>
+ <id>galland</id>
+ <name>Stephane Galland</name>
+ <email>galland@xxxxxxxxxxx</email>
+ <url>http://www.arakhne.org/homes/galland.html</url>
+ <organization />
+ <organizationUrl />
+ <roles>
+ <role>Founder</role>
+ <role>Architect</role>
+ <role>Developer</role>
+ </roles>
+ <timezone />
+ <properties />
+ </developer>
+ <developer>
+ <id>gaud</id>
+ <name>Nicolas Gaud</name>
+ <email>gaud@xxxxxxxxxxx</email>
+ <url>http://www.arakhne.org/homes/gaud.html</url>
+ <organization />
+ <organizationUrl />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ <timezone />
+ <properties />
+ </developer>
+ <developer>
+ <id>willaume</id>
+ <name>Alexandre WILLAUME</name>
+ <email>willaume@xxxxxxxxxxx</email>
+ <url>http://www.arakhne.org/homes/willaume.html</url>
+ <organization />
+ <organizationUrl />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ <timezone />
+ <properties />
+ </developer>
+ </developers>
+
+ <!-- ======================================= -->
+ <!-- ==== Devel Configuration === -->
+ <!-- ======================================= -->
+
+ <distributionManagement>
+ <repository>
+ <id>repository.arakhne.org</id>
+ <name>Arakhn&ecirc; Snapshots Repository</name>
+ <url>file:///srv/arakhne.org/repository/maven/</url>
+ </repository>
+ <site>
+ <id>afc.site.arakhne.org</id>
+ <name>AFC Project Websites Repository</name>
+ <url>file:///srv/arakhne.org/web/maven-sites/</url>
+ </site>
+ </distributionManagement>
+
+ <scm>
+ <connection>scm:svn:svn://svn.tuxfamily.org/svnroot/arakhne/afc/trunk</connection>
+ <developerConnection>scm:svn:svn+ssh://svn.tuxfamily.org/svnroot/arakhne/afc/trunk</developerConnection>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-scm-plugin</artifactId>
+ <configuration>
+ <goals>install</goals>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!-- ======================================= -->
+ <!-- ==== Repositories === -->
+ <!-- ======================================= -->
+
+ <repositories>
+ <repository>
+ <id>Codehaus Snapshots</id>
+ <url>http://snapshots.repository.codehaus.org/</url>
+ </repository>
+ <repository>
+ <id>Arakhn&ecirc; Maven Repository</id>
+ <url>http://download.tuxfamily.org/arakhne/maven/</url>
+ </repository>
+ </repositories>
+
+ <!-- ======================================= -->
+ <!-- ==== Reports === -->
+ <!-- ======================================= -->
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>