/*
* $Id$
* This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc
*
* Copyright (c) 2000-2012 Stephane GALLAND.
* Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports,
* Universite de Technologie de Belfort-Montbeliard.
* Copyright (c) 2013-2016 The original authors, and other authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arakhne.afc.vmutil;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.eclipse.xtext.xbase.lib.Pure;
/**
* Current classpath and associated utility functions.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 5.0
*/
public final class ClasspathUtil {
private ClasspathUtil() {
//
}
/** Replies the classpath at start of the virtual machine.
*
* @return the startup classpath, never <code>null</code>.
* @since 6.0
*/
@Pure
public static Iterator<URL> getStartClasspath() {
return new PathIterator(System.getProperty("java.class.path")); //$NON-NLS-1$
}
/** Replies the current classpath.
*
* @return the current classpath, never <code>null</code>.
* @since 6.0
*/
@Pure
public static Iterator<URL> getClasspath() {
Iterator<URL> iterator = getStartClasspath();
final ClassLoader loader = ClassLoaderFinder.findClassLoader();
try {
final DynamicURLClassLoader dLoader = (DynamicURLClassLoader) loader;
iterator = new FilteringIterator(Arrays.asList(dLoader.getURLs()).iterator());
} catch (ClassCastException exception1) {
if (ClasspathUtil.class.getClassLoader() != loader) {
try {
try (URLClassLoader dLoader = (URLClassLoader) loader) {
iterator = new IteratorIterator(
new FilteringIterator(Arrays.asList(dLoader.getURLs()).iterator()),
iterator);
}
} catch (ClassCastException | IOException exception2) {
//
}
}
}
return iterator;
}
/** Merging Iterator on URLs in a classpath.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 6.0
*/
private static class IteratorIterator implements Iterator<URL> {
private final Iterator<URL> i1;
private final Iterator<URL> i2;
/** Construct the iterator.
*
* @param i1 the first iterator.
* @param i2 the second iterator.
*/
IteratorIterator(Iterator<URL> i1, Iterator<URL> i2) {
assert i1 != null && i2 != null;
this.i1 = i1;
this.i2 = i2;
}
@Override
public boolean hasNext() {
return this.i1.hasNext() || this.i2.hasNext();
}
@Override
public URL next() {
if (this.i1.hasNext()) {
return this.i1.next();
}
return this.i2.next();
}
}
/** Filtering Iterator on URLs in a classpath.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 6.0
*/
private static class FilteringIterator implements Iterator<URL> {
private final Iterator<URL> iterator;
private URL next;
/** Construct the iterator.
*
* @param iterator the iterator to filter.
*/
FilteringIterator(Iterator<URL> iterator) {
assert iterator != null;
this.iterator = iterator;
searchNext();
}
private void searchNext() {
this.next = null;
URL u;
while (this.next == null && this.iterator.hasNext()) {
u = this.iterator.next();
if (u != null) {
this.next = u;
}
}
}
@Override
public boolean hasNext() {
return this.next != null;
}
@Override
public URL next() {
final URL n = this.next;
if (n == null) {
throw new NoSuchElementException();
}
searchNext();
return n;
}
}
/** Iterator on paths in a classpath.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 6.0
*/
private static class PathIterator implements Iterator<URL> {
private String path;
private URL next;
private int nextIndex;
/** Construct the iterator.
*
* @param path the classpath.
*/
PathIterator(String path) {
this.path = path;
this.nextIndex = -1;
searchNext();
}
private void searchNext() {
String path;
int index;
URL url;
this.next = null;
while (this.next == null && this.path != null && this.nextIndex < this.path.length()) {
index = this.path.indexOf(File.pathSeparatorChar, this.nextIndex + 1);
if (index > this.nextIndex + 1) {
path = this.path.substring(this.nextIndex + 1, index);
} else {
path = this.path.substring(this.nextIndex + 1);
// no more element
this.path = null;
}
this.nextIndex = index;
if (path != null && !"".equals(path)) { //$NON-NLS-1$
try {
url = FileSystem.convertStringToURL(path, false, true, false);
if (url != null) {
this.next = url;
}
} catch (AssertionError e) {
throw e;
} catch (Throwable e) {
//
}
}
}
}
@Override
public boolean hasNext() {
return this.next != null;
}
@Override
public URL next() {
final URL n = this.next;
if (n == null) {
throw new NoSuchElementException();
}
searchNext();
return n;
}
}
}