org.apache.openejb.loader.provisining.ProvisioningResolver Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.openejb.loader.provisining;
import org.apache.openejb.loader.Files;
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.SystemInstance;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import static java.util.Collections.singleton;
public class ProvisioningResolver {
public static final String TEMP_DIR = "temp";
public static final String OPENEJB_DEPLOYER_CACHE_FOLDER = "openejb.deployer.cache.folder";
private final Map resolvers = new ConcurrentHashMap<>();
private final ArchiveResolver fallbackResolver = new SimpleUrlResolver();
public ProvisioningResolver() {
resolvers.put("mvn", new MavenResolver());
resolvers.put("http", new HttpResolver());
resolvers.put("https", new HttpResolver());
if (SystemInstance.isInitialized()) {
final String userOnes = SystemInstance.get().getProperty("openejb.provisinig.archive-resolvers");
if (userOnes != null) {
for (final String u : userOnes.split(" *, *")) {
final String c = u.trim();
if (!c.isEmpty()) {
continue;
}
try {
final ArchiveResolver instance = ArchiveResolver.class.cast(ProvisioningResolver.class.getClassLoader().loadClass(c));
addResolver(instance);
} catch (final ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
}
SystemInstance.get().fireEvent(new ProvisiningResolverCreated(this));
}
for (final ArchiveResolver ar : resolvers.values()) {
if (ProvisioningResolverAware.class.isInstance(ar)) {
ProvisioningResolverAware.class.cast(ar).setResolver(this);
}
}
}
public void addResolver(final ArchiveResolver resolver) {
if (resolvers.put(resolver.prefix(), resolver) != null) {
Logger.getLogger(ProvisioningResolver.class.getName()).warning("Overriding resolver " + resolver.prefix() + " with " + resolver);
}
}
public void removeResolver(final ArchiveResolver resolver) {
resolvers.remove(resolver.prefix());
}
public Set realLocation(final String rawLocation) {
// if direct file path then use it
final File file = new File(rawLocation);
if (file.exists()) {
return singleton(file.getAbsolutePath());
}
if (rawLocation.endsWith("*.jar")) {
final File dir = new File(rawLocation.substring(0, rawLocation.length() - "*.jar".length()));
if (dir.exists()) {
final File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(final File dir, final String name) {
return name.endsWith(".jar") || name.endsWith(".zip");
}
});
final Set paths = new HashSet<>(files == null ? 1 : files.length + 1);
if (files != null) {
for (final File f : files) {
paths.add(f.getAbsolutePath());
}
}
paths.add(dir.getAbsolutePath()); // for config it is nice
return paths;
} else {
throw new IllegalArgumentException(dir.getAbsolutePath() + " doesn't exist, *.jar is only supported locally");
}
}
final String protocol = protocol(rawLocation);
ArchiveResolver resolver = resolvers.get(protocol);
if (resolver == null) {
resolver = fallbackResolver;
}
final File destination = cacheFile(resolver.name(rawLocation));
if (destination.exists()) {
return singleton(destination.getAbsolutePath());
}
return singleton(doResolve(rawLocation, destination, resolver));
}
// don't use new URL() since that's really just a prefix
private String protocol(final String rawLocation) {
final int sep = rawLocation.indexOf(':');
if (sep < 1) {
throw new IllegalArgumentException("Not a local file but no prefix specified: " + rawLocation + ". So can't resolve");
}
return rawLocation.substring(0, sep);
}
private String doResolve(final String rawLocation, final File file, final ArchiveResolver resolver) {
final InputStream resolverStream = resolver.resolve(rawLocation);
if (LocalInputStream.class.isInstance(resolverStream)) {
return LocalInputStream.class.cast(resolverStream).path;
}
if (resolverStream != null) {
BufferedInputStream is = null;
try {
is = new BufferedInputStream(resolverStream);
Files.mkdirs(file.getParentFile());
IO.copy(is, file);
return file.getAbsolutePath();
} catch (final IOException ioe) {
throw new IllegalArgumentException(ioe);
} finally {
IO.close(is);
}
} else {
throw new IllegalArgumentException("Could not resolve (" + rawLocation + ')');
}
}
public InputStream resolveStream(final String rawLocation) throws MalformedURLException {
final File file = new File(rawLocation);
if (file.exists()) {
return new LocalInputStream(file.getAbsolutePath());
}
final String protocol = protocol(rawLocation);
final ArchiveResolver resolver = resolvers.get(protocol);
if (resolver != null) {
return resolver.resolve(rawLocation);
}
return null;
}
public static String cache() {
return System.getProperty(OPENEJB_DEPLOYER_CACHE_FOLDER, TEMP_DIR);
}
public static File cacheFile(final String path) {
final String cache = cache();
if (new File(cache).isAbsolute()) {
return new File(cache, path);
}
return new File(SystemInstance.get().getBase().getDirectory(), cache + File.separator + path);
}
@Override
public String toString() {
return "ProvisioningResolver{" +
"resolvers=" + resolvers +
", fallbackResolver=" + fallbackResolver +
'}';
}
// used when a resolver wants to use a local file by calling back this facade resolver
public static final class LocalInputStream extends InputStream {
private final String path;
private FileInputStream stream;
private LocalInputStream(final String path) {
this.path = path;
}
private FileInputStream stream() {
if (stream == null) {
try {
stream = new FileInputStream(path);
} catch (final FileNotFoundException e) {
throw new IllegalStateException(e);
}
}
return stream;
}
@Override
public int read() throws IOException {
return stream().read();
}
@Override
public int read(final byte[] b) throws IOException {
return stream().read(b);
}
@Override
public int read(final byte[] b, final int off, final int len) throws IOException {
return stream().read(b, off, len);
}
@Override
public synchronized void mark(final int readlimit) {
stream().mark(readlimit);
}
@Override
public int available() throws IOException {
return stream().available();
}
@Override
public long skip(final long n) throws IOException {
return stream().skip(n);
}
@Override
public synchronized void reset() throws IOException {
stream().reset();
}
@Override
public boolean markSupported() {
return stream().markSupported();
}
@Override
public void close() throws IOException {
if (stream != null) {
stream.close();
}
super.close();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy