// ========================================================================
// Copyright (c) 2002 Mort Bay Consulting (Australia) Pty. Ltd.
// $Id$
// ========================================================================

//Modified for eXist-db

package org.exist.start;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Supplier;


/**
 * Class to handle CLASSPATH construction
 * @author Jan Hlavat�
 */
public class Classpath implements Iterable<Path> {

    private final static Logger LOG = LogManager.getLogger(Classpath.class);

    final List<Path> _elements = new ArrayList<>();

    public Classpath() {}

    public Classpath(final String initial)
    {
        addClasspath(initial);
    }
        
    public boolean addComponent(final String component) {
        if (component != null && component.length() > 0) {
            try {
                final Path p = Paths.get(component);
                if (Files.exists(p))
                {
                    final Path key = p.toAbsolutePath();
                    if (!_elements.contains(key))
                    {
                        _elements.add(key);
                        return true;
                    }
                }
            } catch (final InvalidPathException e) {
                LOG.error(e.getMessage(), e);
            }
        }
        return false;
    }
    
    public boolean addComponent(final Path component) {
        if (component != null) {
            try {
                if (Files.exists(component)) {
                    final Path key = component.toAbsolutePath();
                    if (!_elements.contains(key)) {
                        _elements.add(key);
                        return true;
                    }
                }
            } catch (final InvalidPathException e) {
                LOG.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public void addClasspath(final String s) {
        if (s != null) {
            final StringTokenizer t = new StringTokenizer(s, File.pathSeparator);
            while (t.hasMoreTokens())
            {
                addComponent(t.nextToken());
            }
        }
    }    

    @Override
    public String toString() {
        final StringBuilder cp = new StringBuilder(1024);
        final int cnt = _elements.size();
        if (cnt >= 1) {
            cp.append(_elements.get(0));
        }
        for (int i=1; i < cnt; i++) {
            cp.append(File.pathSeparatorChar);
            cp.append(_elements.get(i));
        }
        return cp.toString();
    }

    public EXistClassLoader getClassLoader(ClassLoader parent) {
        final URL urls[] = _elements
                .stream()
                .map(Path::toUri)
                .map(u -> {
                    try {
                        return Optional.of(u.toURL());
                    } catch(final MalformedURLException e) {
                        return Optional.<URL>empty();
                    }
                }).filter(ou -> ou.isPresent())
                .map(Optional::get)
                .toArray(sz -> new URL[sz]);

        // try and ensure we have a classloader
        parent = or(
            or(
                or(Optional.ofNullable(parent), () -> Optional.ofNullable(Thread.currentThread().getContextClassLoader())),
                () -> Optional.ofNullable(Classpath.class.getClassLoader())
            ),
            () -> Optional.ofNullable(ClassLoader.getSystemClassLoader())
        ).orElse(null);

        return new EXistClassLoader(urls, parent);
    }

    @Override
    public Iterator<Path> iterator() {
        return _elements.iterator();
    }

    /**
     * Copied from {@link org.exist.util.function.OptionalUtil#or(Optional, Supplier)}
     * as org.exist.start is compiled into a separate Jar and doesn't have
     * the rest of eXist available on the classpath
     */
    private static <T> Optional<T> or(final Optional<T> left, final Supplier<Optional<T>> right) {
        if(left.isPresent()) {
            return left;
        } else {
            return right.get();
        }
    }
}

@@ -3999,31 +3999,30 @@
 ink 
-org.exist.util.function
+com.evolvedbinary.j8fu
 .Opt

Correct javadoc link