mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 15:05:44 +01:00
allow override of core classes
This commit is contained in:
100
scm-webapp/src/main/java/sonia/scm/ClassOverride.java
Normal file
100
scm-webapp/src/main/java/sonia/scm/ClassOverride.java
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, 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;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class ClassOverride
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Class<?> getBind()
|
||||||
|
{
|
||||||
|
return bind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Class<?> getTo()
|
||||||
|
{
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- set methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param bind
|
||||||
|
*/
|
||||||
|
public void setBind(Class<?> bind)
|
||||||
|
{
|
||||||
|
this.bind = bind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param to
|
||||||
|
*/
|
||||||
|
public void setTo(Class<?> to)
|
||||||
|
{
|
||||||
|
this.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private Class<?> bind;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private Class<?> to;
|
||||||
|
}
|
||||||
214
scm-webapp/src/main/java/sonia/scm/ClassOverrides.java
Normal file
214
scm-webapp/src/main/java/sonia/scm/ClassOverrides.java
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, 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;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "overrides")
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class ClassOverrides implements Iterable<ClassOverride>
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String OVERRIDE_PATH = "META-INF/scm/override.xml";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the logger for ClassOverrides
|
||||||
|
*/
|
||||||
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger(ClassOverrides.class);
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static ClassOverrides findOverrides()
|
||||||
|
{
|
||||||
|
ClassOverrides overrides = new ClassOverrides();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Enumeration<URL> overridesEnm =
|
||||||
|
getClassLoader().getResources(OVERRIDE_PATH);
|
||||||
|
JAXBContext context = JAXBContext.newInstance(ClassOverrides.class);
|
||||||
|
|
||||||
|
while (overridesEnm.hasMoreElements())
|
||||||
|
{
|
||||||
|
URL overrideUrl = overridesEnm.nextElement();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ClassOverrides co =
|
||||||
|
(ClassOverrides) context.createUnmarshaller().unmarshal(
|
||||||
|
overrideUrl);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.error("could not load ".concat(overrideUrl.toExternalForm()),
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.error("could not load overrides", ex);
|
||||||
|
}
|
||||||
|
catch (JAXBException ex)
|
||||||
|
{
|
||||||
|
logger.error("could not create jaxb context for ClassOverrides", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return overrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Class<T> getOverride(Class<T> clazz){
|
||||||
|
Class<T> implementation = null;
|
||||||
|
for ( ClassOverride co : getOverrides() ){
|
||||||
|
if ( co.getBind().equals(clazz) ){
|
||||||
|
implementation = (Class<T>) co.getTo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static ClassLoader getClassLoader()
|
||||||
|
{
|
||||||
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
|
||||||
|
if (classLoader == null)
|
||||||
|
{
|
||||||
|
classLoader = ClassOverrides.class.getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
return classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param overrides
|
||||||
|
*/
|
||||||
|
public void append(ClassOverrides overrides)
|
||||||
|
{
|
||||||
|
getOverrides().addAll(overrides.getOverrides());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<ClassOverride> iterator()
|
||||||
|
{
|
||||||
|
return getOverrides().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<ClassOverride> getOverrides()
|
||||||
|
{
|
||||||
|
if (overrides == null)
|
||||||
|
{
|
||||||
|
overrides = new ArrayList<ClassOverride>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return overrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- set methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param overrides
|
||||||
|
*/
|
||||||
|
public void setOverrides(List<ClassOverride> overrides)
|
||||||
|
{
|
||||||
|
this.overrides = overrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
@XmlElement(name = "override")
|
||||||
|
private List<ClassOverride> overrides;
|
||||||
|
}
|
||||||
@@ -193,6 +193,7 @@ public class ScmServletModule extends ServletModule
|
|||||||
{
|
{
|
||||||
this.pluginLoader = pluginLoader;
|
this.pluginLoader = pluginLoader;
|
||||||
this.bindExtProcessor = bindExtProcessor;
|
this.bindExtProcessor = bindExtProcessor;
|
||||||
|
this.overrides = ClassOverrides.findOverrides();
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -219,13 +220,13 @@ public class ScmServletModule extends ServletModule
|
|||||||
DefaultRepositoryProvider.class).in(RequestScoped.class);
|
DefaultRepositoryProvider.class).in(RequestScoped.class);
|
||||||
|
|
||||||
// bind core
|
// bind core
|
||||||
bind(StoreFactory.class).to(JAXBStoreFactory.class);
|
bind(StoreFactory.class, JAXBStoreFactory.class);
|
||||||
bind(ScmConfiguration.class).toInstance(config);
|
bind(ScmConfiguration.class).toInstance(config);
|
||||||
bind(PluginLoader.class).toInstance(pluginLoader);
|
bind(PluginLoader.class).toInstance(pluginLoader);
|
||||||
bind(PluginManager.class).to(DefaultPluginManager.class);
|
bind(PluginManager.class, DefaultPluginManager.class);
|
||||||
bind(KeyGenerator.class).toInstance(cu.getKeyGenerator());
|
bind(KeyGenerator.class).toInstance(cu.getKeyGenerator());
|
||||||
bind(CipherHandler.class).toInstance(cu.getCipherHandler());
|
bind(CipherHandler.class).toInstance(cu.getCipherHandler());
|
||||||
bind(EncryptionHandler.class).to(MessageDigestEncryptionHandler.class);
|
bind(EncryptionHandler.class, MessageDigestEncryptionHandler.class);
|
||||||
bindExtProcessor.bindExtensions(binder());
|
bindExtProcessor.bindExtensions(binder());
|
||||||
|
|
||||||
Class<? extends FileSystem> fileSystem =
|
Class<? extends FileSystem> fileSystem =
|
||||||
@@ -239,37 +240,37 @@ public class ScmServletModule extends ServletModule
|
|||||||
bind(FileSystem.class).to(fileSystem);
|
bind(FileSystem.class).to(fileSystem);
|
||||||
|
|
||||||
// bind security stuff
|
// bind security stuff
|
||||||
bind(AuthenticationManager.class).to(ChainAuthenticatonManager.class);
|
bind(AuthenticationManager.class, ChainAuthenticatonManager.class);
|
||||||
bind(LocalSecurityContextHolder.class);
|
bind(LocalSecurityContextHolder.class);
|
||||||
bind(WebSecurityContext.class).annotatedWith(Names.named("userSession")).to(
|
bind(WebSecurityContext.class).annotatedWith(Names.named("userSession")).to(
|
||||||
BasicSecurityContext.class);
|
BasicSecurityContext.class);
|
||||||
bind(SecurityContext.class).toProvider(SecurityContextProvider.class);
|
bind(SecurityContext.class).toProvider(SecurityContextProvider.class);
|
||||||
bind(WebSecurityContext.class).toProvider(SecurityContextProvider.class);
|
bind(WebSecurityContext.class).toProvider(SecurityContextProvider.class);
|
||||||
bind(AdministrationContext.class).to(DefaultAdministrationContext.class);
|
bind(AdministrationContext.class, DefaultAdministrationContext.class);
|
||||||
|
|
||||||
// bind security cache
|
// bind security cache
|
||||||
bind(CacheManager.class).to(EhCacheManager.class);
|
bind(CacheManager.class, EhCacheManager.class);
|
||||||
|
|
||||||
// bind(RepositoryManager.class).annotatedWith(Undecorated.class).to(
|
// bind(RepositoryManager.class).annotatedWith(Undecorated.class).to(
|
||||||
// BasicRepositoryManager.class);
|
// BasicRepositoryManager.class);
|
||||||
bind(RepositoryManager.class).to(XmlRepositoryManager.class);
|
bind(RepositoryManager.class, XmlRepositoryManager.class);
|
||||||
bind(UserManager.class).to(XmlUserManager.class);
|
bind(UserManager.class, XmlUserManager.class);
|
||||||
bind(GroupManager.class).to(XmlGroupManager.class);
|
bind(GroupManager.class, XmlGroupManager.class);
|
||||||
bind(CGIExecutorFactory.class).to(DefaultCGIExecutorFactory.class);
|
bind(CGIExecutorFactory.class, DefaultCGIExecutorFactory.class);
|
||||||
bind(ChangesetViewerUtil.class);
|
bind(ChangesetViewerUtil.class);
|
||||||
bind(RepositoryBrowserUtil.class);
|
bind(RepositoryBrowserUtil.class);
|
||||||
|
|
||||||
// bind httpclient
|
// bind httpclient
|
||||||
bind(HttpClient.class).to(URLHttpClient.class);
|
bind(HttpClient.class, URLHttpClient.class);
|
||||||
|
|
||||||
// bind resourcemanager
|
// bind resourcemanager
|
||||||
if (context.getStage() == Stage.DEVELOPMENT)
|
if (context.getStage() == Stage.DEVELOPMENT)
|
||||||
{
|
{
|
||||||
bind(ResourceManager.class).to(DevelopmentResourceManager.class);
|
bind(ResourceManager.class, DevelopmentResourceManager.class);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bind(ResourceManager.class).to(DefaultResourceManager.class);
|
bind(ResourceManager.class, DefaultResourceManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind url provider staff
|
// bind url provider staff
|
||||||
@@ -378,6 +379,37 @@ public class ScmServletModule extends ServletModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param clazz
|
||||||
|
* @param defaultImplementation
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
private <T> void bind(Class<T> clazz,
|
||||||
|
Class<? extends T> defaultImplementation)
|
||||||
|
{
|
||||||
|
Class<? extends T> implementation = overrides.getOverride(clazz);
|
||||||
|
|
||||||
|
if (implementation != null)
|
||||||
|
{
|
||||||
|
logger.info("bind {} to override {}", clazz, implementation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
implementation = defaultImplementation;
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("bind {} to defaul implementation {}", clazz,
|
||||||
|
implementation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bind(clazz).to(implementation);
|
||||||
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -440,6 +472,9 @@ public class ScmServletModule extends ServletModule
|
|||||||
/** Field description */
|
/** Field description */
|
||||||
private BindingExtensionProcessor bindExtProcessor;
|
private BindingExtensionProcessor bindExtProcessor;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private ClassOverrides overrides;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private PluginLoader pluginLoader;
|
private PluginLoader pluginLoader;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user