mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 19:45:51 +01:00
implement WebResourceLoaders for loading plugin web resources
This commit is contained in:
@@ -38,6 +38,7 @@ package sonia.scm.plugin;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -81,13 +82,23 @@ public interface PluginLoader
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<Plugin> getInstalledPlugins();
|
||||
public Collection<PluginWrapper> getInstalledPlugins();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
* Returns a {@link ClassLoader} which is able to load classes and resources
|
||||
* from the webapp and all installed plugins.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* @return uber classloader
|
||||
*/
|
||||
public ClassLoader getUberClassLoader();
|
||||
|
||||
/**
|
||||
* Returns a {@link WebResourceLoader} which is able to load web resources
|
||||
* from the webapp and all installed plugins.
|
||||
*
|
||||
*
|
||||
* @return uber webresourceloader
|
||||
*/
|
||||
public UberWebResourceLoader getUberWebResourceLoader();
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ package sonia.scm.plugin;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Wrapper for a {@link Plugin}. The wrapper holds the directory and the
|
||||
* {@link ClassLoader}, which is able to load plugin classes.
|
||||
* Wrapper for a {@link Plugin}. The wrapper holds the directory,
|
||||
* {@link ClassLoader} and {@link WebResourceLoader} of a plugin.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
@@ -50,12 +50,15 @@ public final class PluginWrapper
|
||||
*
|
||||
* @param plugin wrapped plugin
|
||||
* @param classLoader plugin class loader
|
||||
* @param webResourceLoader web resource loader
|
||||
* @param directory plugin directory
|
||||
*/
|
||||
public PluginWrapper(Plugin plugin, ClassLoader classLoader, Path directory)
|
||||
public PluginWrapper(Plugin plugin, ClassLoader classLoader,
|
||||
WebResourceLoader webResourceLoader, Path directory)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.classLoader = classLoader;
|
||||
this.webResourceLoader = webResourceLoader;
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@@ -105,6 +108,17 @@ public final class PluginWrapper
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link WebResourceLoader} for this plugin.
|
||||
*
|
||||
*
|
||||
* @return web resource loader
|
||||
*/
|
||||
public WebResourceLoader getWebResourceLoader()
|
||||
{
|
||||
return webResourceLoader;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** plugin class loader */
|
||||
@@ -115,4 +129,7 @@ public final class PluginWrapper
|
||||
|
||||
/** plugin */
|
||||
private final Plugin plugin;
|
||||
|
||||
/** plugin web resource loader */
|
||||
private final WebResourceLoader webResourceLoader;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
* Load resources from {@link ServletContext} and from the installed plugins.
|
||||
* The UberWebResourceLoader will first look into the {@link ServletContext} and
|
||||
* afterwards it will search the plugin directories.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface UberWebResourceLoader extends WebResourceLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns all {@link URL} objects for the given path. The method will collect
|
||||
* all resources from {@link ServletContext} and all plugin directories which
|
||||
* matches the given path. The method will return an empty list, if no url
|
||||
* could be found for the given path.
|
||||
*
|
||||
* @param path resource path
|
||||
*
|
||||
* @return list of url objects for the given path
|
||||
*/
|
||||
public List<URL> getResources(String path);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
* The WebResourceLoader is able to load web resources. The resources are loaded
|
||||
* from a plugin webapp directory or from the {@link ServletContext}, according
|
||||
* to its implementation. The {@link UberWebResourceLoader} is able to load
|
||||
* resources from the {@link ServletContext} and all plugin directories.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface WebResourceLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a {@link URL} for the given path. The method will return null if no
|
||||
* resources could be found for the given path.
|
||||
*
|
||||
* @param path resource path
|
||||
*
|
||||
* @return url object for the given path or null
|
||||
*/
|
||||
public URL getResource(String path);
|
||||
}
|
||||
@@ -95,8 +95,8 @@ public enum ResourceType
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String contentType;
|
||||
private final String contentType;
|
||||
|
||||
/** Field description */
|
||||
private String extension;
|
||||
private final String extension;
|
||||
}
|
||||
|
||||
@@ -209,7 +209,8 @@ public class ScmContextListener extends GuiceServletContextListener
|
||||
*/
|
||||
private Injector getDefaultInjector(ServletContext servletCtx)
|
||||
{
|
||||
DefaultPluginLoader pluginLoader = new DefaultPluginLoader(parent, plugins);
|
||||
DefaultPluginLoader pluginLoader = new DefaultPluginLoader(servletCtx,
|
||||
parent, plugins);
|
||||
|
||||
ClassOverrides overrides =
|
||||
ClassOverrides.findOverrides(pluginLoader.getUberClassLoader());
|
||||
|
||||
@@ -56,6 +56,8 @@ import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
@@ -81,13 +83,17 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
* @param servletContext
|
||||
* @param parent
|
||||
* @param wrappedPlugins
|
||||
* @param installedPlugins
|
||||
*/
|
||||
public DefaultPluginLoader(ClassLoader parent,
|
||||
Set<PluginWrapper> wrappedPlugins)
|
||||
public DefaultPluginLoader(ServletContext servletContext, ClassLoader parent,
|
||||
Set<PluginWrapper> installedPlugins)
|
||||
{
|
||||
this.uberClassLoader = new UberClassLoader(parent, wrappedPlugins);
|
||||
this.installedPlugins = installedPlugins;
|
||||
this.uberClassLoader = new UberClassLoader(parent, installedPlugins);
|
||||
this.uberWebResourceLoader =
|
||||
new DefaultUberWebResourceLoader(servletContext, installedPlugins);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -96,16 +102,8 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
|
||||
modules = getInstalled(parent, context, PATH_MODULECONFIG);
|
||||
|
||||
// hidden plugins ???
|
||||
Set<Plugin> ips = getInstalled(parent, context, PATH_PLUGINCONFIG);
|
||||
Builder<Plugin> builder = ImmutableSet.builder();
|
||||
|
||||
builder.addAll(ips);
|
||||
builder.addAll(PluginsInternal.unwrap(wrappedPlugins));
|
||||
plugins = builder.build();
|
||||
|
||||
appendExtensions(multiple, single, extensions, modules);
|
||||
appendExtensions(multiple, single, extensions, plugins);
|
||||
appendExtensions(multiple, single, extensions, unwrap());
|
||||
}
|
||||
catch (IOException | JAXBException ex)
|
||||
{
|
||||
@@ -127,7 +125,7 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
logger.info("start processing extensions");
|
||||
|
||||
appendExtensions(multiple, single, extensions, modules);
|
||||
appendExtensions(multiple, single, extensions, plugins);
|
||||
appendExtensions(multiple, single, extensions, unwrap());
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
@@ -173,9 +171,9 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Collection<Plugin> getInstalledPlugins()
|
||||
public Collection<PluginWrapper> getInstalledPlugins()
|
||||
{
|
||||
return plugins;
|
||||
return installedPlugins;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,6 +188,18 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
return uberClassLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UberWebResourceLoader getUberWebResourceLoader()
|
||||
{
|
||||
return uberWebResourceLoader;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -242,6 +252,17 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Iterable<Plugin> unwrap()
|
||||
{
|
||||
return PluginsInternal.unwrap(installedPlugins);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -282,15 +303,18 @@ public class DefaultPluginLoader implements PluginLoader
|
||||
/** Field description */
|
||||
private final ClassLoader uberClassLoader;
|
||||
|
||||
/** Field description */
|
||||
private final UberWebResourceLoader uberWebResourceLoader;
|
||||
|
||||
/** Field description */
|
||||
private Set<PluginWrapper> installedPlugins;
|
||||
|
||||
/** Field description */
|
||||
private Set<ScmModule> modules;
|
||||
|
||||
/** Field description */
|
||||
private Set<Class> multiple = Sets.newHashSet();
|
||||
|
||||
/** Field description */
|
||||
private Set<Plugin> plugins;
|
||||
|
||||
/** Field description */
|
||||
private Set<Class> single = Sets.newHashSet();
|
||||
|
||||
|
||||
@@ -98,10 +98,6 @@ public class DefaultPluginManager implements PluginManager
|
||||
/** Field description */
|
||||
public static final String ENCODING = "UTF-8";
|
||||
|
||||
/** Field description */
|
||||
private static final String ADVANCED_CONFIGURATION =
|
||||
"advanced-configuration.xml";
|
||||
|
||||
/** the logger for DefaultPluginManager */
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(DefaultPluginManager.class);
|
||||
@@ -133,10 +129,11 @@ public class DefaultPluginManager implements PluginManager
|
||||
this.configuration = configuration;
|
||||
this.cache = cacheManager.getCache(CACHE_NAME);
|
||||
this.clientProvider = clientProvider;
|
||||
installedPlugins = new HashMap<String, Plugin>();
|
||||
installedPlugins = new HashMap<>();
|
||||
|
||||
for (Plugin plugin : pluginLoader.getInstalledPlugins())
|
||||
for (PluginWrapper wrapper : pluginLoader.getInstalledPlugins())
|
||||
{
|
||||
Plugin plugin = wrapper.getPlugin();
|
||||
PluginInformation info = plugin.getInformation();
|
||||
|
||||
if ((info != null) && info.isValid())
|
||||
@@ -247,15 +244,17 @@ public class DefaultPluginManager implements PluginManager
|
||||
throw new PluginConditionFailedException(condition);
|
||||
}
|
||||
|
||||
/*AetherPluginHandler aph = new AetherPluginHandler(this, context,
|
||||
configuration);
|
||||
Collection<PluginRepository> repositories =
|
||||
Sets.newHashSet(new PluginRepository("package-repository",
|
||||
"file://".concat(tempDirectory.getAbsolutePath())));
|
||||
|
||||
aph.setPluginRepositories(repositories);
|
||||
|
||||
aph.install(plugin.getInformation().getId());*/
|
||||
/*
|
||||
* AetherPluginHandler aph = new AetherPluginHandler(this, context,
|
||||
* configuration);
|
||||
* Collection<PluginRepository> repositories =
|
||||
* Sets.newHashSet(new PluginRepository("package-repository",
|
||||
* "file://".concat(tempDirectory.getAbsolutePath())));
|
||||
*
|
||||
* aph.setPluginRepositories(repositories);
|
||||
*
|
||||
* aph.install(plugin.getInformation().getId());
|
||||
*/
|
||||
plugin.getInformation().setState(PluginState.INSTALLED);
|
||||
installedPlugins.put(plugin.getInformation().getId(), plugin);
|
||||
|
||||
@@ -300,12 +299,14 @@ public class DefaultPluginManager implements PluginManager
|
||||
throw new PluginNotInstalledException(id.concat(" is not install"));
|
||||
}
|
||||
|
||||
/*if (pluginHandler == null)
|
||||
{
|
||||
getPluginCenter();
|
||||
}
|
||||
|
||||
pluginHandler.uninstall(id);*/
|
||||
/*
|
||||
* if (pluginHandler == null)
|
||||
* {
|
||||
* getPluginCenter();
|
||||
* }
|
||||
*
|
||||
* pluginHandler.uninstall(id);
|
||||
*/
|
||||
installedPlugins.remove(id);
|
||||
preparePlugins(getPluginCenter());
|
||||
}
|
||||
@@ -394,7 +395,7 @@ public class DefaultPluginManager implements PluginManager
|
||||
AssertUtil.assertIsNotNull(predicate);
|
||||
SecurityUtil.assertIsAdmin();
|
||||
|
||||
Set<PluginInformation> infoSet = new HashSet<PluginInformation>();
|
||||
Set<PluginInformation> infoSet = new HashSet<>();
|
||||
|
||||
filter(infoSet, getInstalled(), predicate);
|
||||
filter(infoSet, getPluginCenter().getPlugins(), predicate);
|
||||
@@ -431,7 +432,7 @@ public class DefaultPluginManager implements PluginManager
|
||||
{
|
||||
SecurityUtil.assertIsAdmin();
|
||||
|
||||
Set<PluginInformation> availablePlugins = new HashSet<PluginInformation>();
|
||||
Set<PluginInformation> availablePlugins = new HashSet<>();
|
||||
Set<PluginInformation> centerPlugins = getPluginCenter().getPlugins();
|
||||
|
||||
for (PluginInformation info : centerPlugins)
|
||||
@@ -470,7 +471,7 @@ public class DefaultPluginManager implements PluginManager
|
||||
{
|
||||
SecurityUtil.assertIsAdmin();
|
||||
|
||||
Set<PluginInformation> infoSet = new LinkedHashSet<PluginInformation>();
|
||||
Set<PluginInformation> infoSet = new LinkedHashSet<>();
|
||||
|
||||
for (Plugin plugin : installedPlugins.values())
|
||||
{
|
||||
@@ -642,16 +643,18 @@ public class DefaultPluginManager implements PluginManager
|
||||
preparePlugins(center);
|
||||
cache.put(PluginCenter.class.getName(), center);
|
||||
|
||||
/*if (pluginHandler == null)
|
||||
{
|
||||
pluginHandler = new AetherPluginHandler(this,
|
||||
SCMContext.getContext(), configuration,
|
||||
advancedPluginConfiguration);
|
||||
}
|
||||
|
||||
pluginHandler.setPluginRepositories(center.getRepositories());*/
|
||||
/*
|
||||
* if (pluginHandler == null)
|
||||
* {
|
||||
* pluginHandler = new AetherPluginHandler(this,
|
||||
* SCMContext.getContext(), configuration,
|
||||
* advancedPluginConfiguration);
|
||||
* }
|
||||
*
|
||||
* pluginHandler.setPluginRepositories(center.getRepositories());
|
||||
*/
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (IOException | JAXBException ex)
|
||||
{
|
||||
logger.error("could not load plugins from plugin center", ex);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link UberWebResourceLoader}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DefaultUberWebResourceLoader implements UberWebResourceLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for DefaultUberWebResourceLoader
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(DefaultUberWebResourceLoader.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param servletContext
|
||||
* @param plugins
|
||||
*/
|
||||
public DefaultUberWebResourceLoader(ServletContext servletContext,
|
||||
Iterable<PluginWrapper> plugins)
|
||||
{
|
||||
this.servletContext = servletContext;
|
||||
this.plugins = plugins;
|
||||
this.cache = CacheBuilder.newBuilder().build();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public URL getResource(String path)
|
||||
{
|
||||
URL resource = cache.getIfPresent(path);
|
||||
|
||||
if (resource == null)
|
||||
{
|
||||
resource = find(path);
|
||||
|
||||
if (resource != null)
|
||||
{
|
||||
cache.put(path, resource);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.trace("return web resource {} from cache", path);
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<URL> getResources(String path)
|
||||
{
|
||||
|
||||
// caching ???
|
||||
Builder<URL> resources = ImmutableList.builder();
|
||||
|
||||
try
|
||||
{
|
||||
URL ctxResource = servletContext.getResource(path);
|
||||
|
||||
if (ctxResource != null)
|
||||
{
|
||||
logger.trace("found path {} at ServletContext", path);
|
||||
resources.add(ctxResource);
|
||||
}
|
||||
|
||||
for (PluginWrapper wrapper : plugins)
|
||||
{
|
||||
URL resource = wrapper.getWebResourceLoader().getResource(path);
|
||||
|
||||
if (resource != null)
|
||||
{
|
||||
resources.add(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
|
||||
// TODO define an extra exception
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
|
||||
return resources.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Cache<String, URL> getCache()
|
||||
{
|
||||
return cache;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private URL find(String path)
|
||||
{
|
||||
URL resource = null;
|
||||
|
||||
try
|
||||
{
|
||||
resource = servletContext.getResource(path);
|
||||
|
||||
if (resource == null)
|
||||
{
|
||||
for (PluginWrapper wrapper : plugins)
|
||||
{
|
||||
resource = wrapper.getWebResourceLoader().getResource(path);
|
||||
|
||||
if (resource != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.trace("found path {} at ServletContext", path);
|
||||
}
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
|
||||
// TODO define an extra exception
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Cache<String, URL> cache;
|
||||
|
||||
/** Field description */
|
||||
private final Iterable<PluginWrapper> plugins;
|
||||
|
||||
/** Field description */
|
||||
private final ServletContext servletContext;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Load web resources from a plugin webapp directory.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class PathWebResourceLoader implements WebResourceLoader
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String DEFAULT_SEPARATOR = "/";
|
||||
|
||||
/**
|
||||
* the logger for PathWebResourceLoader
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(PathWebResourceLoader.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param directory
|
||||
*/
|
||||
public PathWebResourceLoader(Path directory)
|
||||
{
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public URL getResource(String path)
|
||||
{
|
||||
URL resource = null;
|
||||
Path file = directory.resolve(filePath(path));
|
||||
|
||||
if (Files.exists(file))
|
||||
{
|
||||
logger.trace("found path {} at {}", path, file);
|
||||
|
||||
try
|
||||
{
|
||||
resource = file.toUri().toURL();
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
logger.error("could not transform path to url", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String filePath(String path)
|
||||
{
|
||||
|
||||
// TODO handle illegal path parts, such as ..
|
||||
String filePath = filePath(DEFAULT_SEPARATOR, path);
|
||||
|
||||
if (!DEFAULT_SEPARATOR.equals(File.separator))
|
||||
{
|
||||
filePath = filePath(File.separator, path);
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param separator
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String filePath(String separator, String path)
|
||||
{
|
||||
String filePath = path;
|
||||
|
||||
if (filePath.startsWith(separator))
|
||||
{
|
||||
filePath = filePath.substring(separator.length());
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Path directory;
|
||||
}
|
||||
@@ -491,7 +491,8 @@ public final class PluginProcessor
|
||||
throws IOException
|
||||
{
|
||||
PluginWrapper wrapper = null;
|
||||
Path descriptor = smp.getPath().resolve(PluginConstants.FILE_DESCRIPTOR);
|
||||
Path directory = smp.getPath();
|
||||
Path descriptor = directory.resolve(PluginConstants.FILE_DESCRIPTOR);
|
||||
|
||||
if (Files.exists(descriptor))
|
||||
{
|
||||
@@ -499,7 +500,8 @@ public final class PluginProcessor
|
||||
|
||||
Plugin plugin = createPlugin(cl, descriptor);
|
||||
|
||||
wrapper = new PluginWrapper(plugin, cl, smp.getPath());
|
||||
wrapper = new PluginWrapper(plugin, cl,
|
||||
new PathWebResourceLoader(directory), directory);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -117,7 +118,7 @@ public abstract class AbstractResourceManager implements ResourceManager
|
||||
@Override
|
||||
public List<Resource> getResources(ResourceType type)
|
||||
{
|
||||
List<Resource> resources = new ArrayList<Resource>();
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
|
||||
for (Entry<ResourceKey, Resource> e : resourceMap.entrySet())
|
||||
{
|
||||
@@ -140,14 +141,14 @@ public abstract class AbstractResourceManager implements ResourceManager
|
||||
*/
|
||||
protected List<String> getScriptResources()
|
||||
{
|
||||
List<String> resources = new ArrayList<String>();
|
||||
Collection<Plugin> plugins = pluginLoader.getInstalledPlugins();
|
||||
List<String> resources = new ArrayList<>();
|
||||
Collection<PluginWrapper> wrappers = pluginLoader.getInstalledPlugins();
|
||||
|
||||
if (plugins != null)
|
||||
if (wrappers != null)
|
||||
{
|
||||
for (Plugin plugin : plugins)
|
||||
for (PluginWrapper plugin : wrappers)
|
||||
{
|
||||
processPlugin(resources, plugin);
|
||||
processPlugin(resources, plugin.getPlugin());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,12 +236,7 @@ public abstract class AbstractResourceManager implements ResourceManager
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.type != other.type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return this.type == other.type;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,10 +287,10 @@ public abstract class AbstractResourceManager implements ResourceManager
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
private final String name;
|
||||
|
||||
/** Field description */
|
||||
private ResourceType type;
|
||||
private final ResourceType type;
|
||||
}
|
||||
|
||||
|
||||
@@ -307,8 +303,7 @@ public abstract class AbstractResourceManager implements ResourceManager
|
||||
protected Set<ResourceHandler> resourceHandlers;
|
||||
|
||||
/** Field description */
|
||||
protected Map<ResourceKey, Resource> resourceMap = new HashMap<ResourceKey,
|
||||
Resource>();
|
||||
protected Map<ResourceKey, Resource> resourceMap = new HashMap<>();
|
||||
|
||||
/** Field description */
|
||||
protected ServletContext servletContext;
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DefaultUberWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static URL BITBUCKET;
|
||||
|
||||
/** Field description */
|
||||
private static URL GITHUB;
|
||||
|
||||
/** Field description */
|
||||
private static URL SCM_MANAGER;
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void prepare() throws MalformedURLException
|
||||
{
|
||||
SCM_MANAGER = new URL("https://www.scm-manager.org");
|
||||
BITBUCKET = new URL("https://bitbucket.org");
|
||||
GITHUB = new URL("https://github.com");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
@Test
|
||||
public void testGetResourceFromCache() throws MalformedURLException
|
||||
{
|
||||
when(servletContext.getResource("/myresource")).thenReturn(SCM_MANAGER);
|
||||
|
||||
DefaultUberWebResourceLoader resourceLoader =
|
||||
new DefaultUberWebResourceLoader(servletContext,
|
||||
new ArrayList<PluginWrapper>());
|
||||
|
||||
resourceLoader.getCache().put("/myresource", GITHUB);
|
||||
|
||||
URL resource = resourceLoader.getResource("/myresource");
|
||||
|
||||
assertSame(GITHUB, resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testGetResourceFromDirectory() throws IOException
|
||||
{
|
||||
File directory = temp.newFolder();
|
||||
File file = file(directory, "myresource");
|
||||
PluginWrapper wrapper = createPluginWrapper(directory);
|
||||
List<PluginWrapper> plugins = Lists.newArrayList(wrapper);
|
||||
WebResourceLoader resourceLoader =
|
||||
new DefaultUberWebResourceLoader(servletContext, plugins);
|
||||
|
||||
assertEquals(file.toURI().toURL(),
|
||||
resourceLoader.getResource("/myresource"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
@Test
|
||||
public void testGetResourceFromServletContext() throws MalformedURLException
|
||||
{
|
||||
when(servletContext.getResource("/myresource")).thenReturn(SCM_MANAGER);
|
||||
|
||||
WebResourceLoader resourceLoader =
|
||||
new DefaultUberWebResourceLoader(servletContext,
|
||||
new ArrayList<PluginWrapper>());
|
||||
URL resource = resourceLoader.getResource("/myresource");
|
||||
|
||||
assertSame(SCM_MANAGER, resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testGetResources() throws IOException
|
||||
{
|
||||
when(servletContext.getResource("/myresource")).thenReturn(BITBUCKET);
|
||||
|
||||
File directory = temp.newFolder();
|
||||
File file = file(directory, "myresource");
|
||||
PluginWrapper wrapper = createPluginWrapper(directory);
|
||||
List<PluginWrapper> plugins = Lists.newArrayList(wrapper);
|
||||
|
||||
UberWebResourceLoader resourceLoader =
|
||||
new DefaultUberWebResourceLoader(servletContext, plugins);
|
||||
|
||||
assertThat(resourceLoader.getResources("/myresource"),
|
||||
containsInAnyOrder(file.toURI().toURL(), BITBUCKET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param directory
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private PluginWrapper createPluginWrapper(File directory)
|
||||
{
|
||||
return createPluginWrapper(directory.toPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param directory
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private PluginWrapper createPluginWrapper(Path directory)
|
||||
{
|
||||
return new PluginWrapper(null, null, new PathWebResourceLoader(directory),
|
||||
directory);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@Mock
|
||||
private ServletContext servletContext;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class PathWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testGetResource() throws IOException
|
||||
{
|
||||
File directory = temp.newFolder();
|
||||
URL url = file(directory, "myresource").toURI().toURL();
|
||||
|
||||
WebResourceLoader resourceLoader =
|
||||
new PathWebResourceLoader(directory.toPath());
|
||||
|
||||
assertEquals(url, resourceLoader.getResource("/myresource"));
|
||||
assertEquals(url, resourceLoader.getResource("myresource"));
|
||||
assertNull(resourceLoader.getResource("other"));
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public abstract class WebResourceLoaderTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param directory
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected File file(File directory, String path) throws IOException
|
||||
{
|
||||
IOUtil.mkdirs(directory);
|
||||
|
||||
File file = new File(directory, path);
|
||||
|
||||
Files.append("a", file, Charsets.UTF_8);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@Rule
|
||||
public TemporaryFolder temp = new TemporaryFolder();
|
||||
}
|
||||
Reference in New Issue
Block a user