mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 17:05:43 +01:00
merge with branch issue-345
This commit is contained in:
@@ -142,6 +142,7 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import sonia.scm.cache.GuavaCacheManager;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -272,8 +273,8 @@ public class ScmServletModule extends ServletModule
|
||||
bind(WebSecurityContext.class).to(BasicSecurityContext.class);
|
||||
bind(AdministrationContext.class, DefaultAdministrationContext.class);
|
||||
|
||||
// bind security cache
|
||||
bind(CacheManager.class, EhCacheManager.class);
|
||||
// bind cache
|
||||
bind(CacheManager.class, GuavaCacheManager.class);
|
||||
|
||||
// bind dao
|
||||
bind(GroupDAO.class, XmlGroupDAO.class);
|
||||
|
||||
116
scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurations.java
vendored
Normal file
116
scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurations.java
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public final class CacheConfigurations
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for CacheConfigurations
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(CacheConfigurations.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private CacheConfigurations() {}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param loadingClass
|
||||
* @param resource
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Iterator<URL> findModuleResources(Class<?> loadingClass,
|
||||
String resource)
|
||||
{
|
||||
Iterator<URL> it = null;
|
||||
|
||||
try
|
||||
{
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
if (classLoader == null)
|
||||
{
|
||||
classLoader = loadingClass.getClassLoader();
|
||||
}
|
||||
|
||||
Enumeration<URL> enm = classLoader.getResources(resource);
|
||||
|
||||
if (enm != null)
|
||||
{
|
||||
it = Iterators.forEnumeration(enm);
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.error("could not read module resources", ex);
|
||||
}
|
||||
|
||||
if (it == null)
|
||||
{
|
||||
it = Iterators.emptyIterator();
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
}
|
||||
85
scm-webapp/src/main/java/sonia/scm/cache/CacheException.java
vendored
Normal file
85
scm-webapp/src/main/java/sonia/scm/cache/CacheException.java
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class CacheException extends RuntimeException
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -1108209749696572319L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public CacheException() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public CacheException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param cause
|
||||
*/
|
||||
public CacheException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public CacheException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
147
scm-webapp/src/main/java/sonia/scm/cache/CopyStrategy.java
vendored
Normal file
147
scm-webapp/src/main/java/sonia/scm/cache/CopyStrategy.java
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.io.DeepCopy;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public enum CopyStrategy
|
||||
{
|
||||
|
||||
NONE(false, false), READ(true, false), WRITE(false, true),
|
||||
READWRITE(true, true);
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param copyOnRead
|
||||
* @param copyOnWrite
|
||||
*/
|
||||
private CopyStrategy(boolean copyOnRead, boolean copyOnWrite)
|
||||
{
|
||||
this.copyOnRead = copyOnRead;
|
||||
this.copyOnWrite = copyOnWrite;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static CopyStrategy fromString(String value)
|
||||
{
|
||||
return valueOf(value.toUpperCase(Locale.ENGLISH).replace("-", ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param object
|
||||
* @param <T>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public <T> T copyOnRead(T object)
|
||||
{
|
||||
return copyOnRead
|
||||
? deepCopy(object)
|
||||
: object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param object
|
||||
* @param <T>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public <T> T copyOnWrite(T object)
|
||||
{
|
||||
return copyOnWrite
|
||||
? deepCopy(object)
|
||||
: object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param object
|
||||
* @param <T>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private <T> T deepCopy(T object)
|
||||
{
|
||||
T copy = null;
|
||||
|
||||
try
|
||||
{
|
||||
copy = DeepCopy.copy(object);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new CacheException(
|
||||
"could not create a copy of ".concat(object.toString()), ex);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private boolean copyOnRead;
|
||||
|
||||
/** Field description */
|
||||
private boolean copyOnWrite;
|
||||
}
|
||||
@@ -35,6 +35,8 @@ package sonia.scm.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -186,6 +188,18 @@ public class EhCache<K, V> implements Cache<K, V>
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
net.sf.ehcache.Cache getCacheImplementation()
|
||||
{
|
||||
return cache;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
|
||||
475
scm-webapp/src/main/java/sonia/scm/cache/EhCacheConfigurationReader.java
vendored
Normal file
475
scm-webapp/src/main/java/sonia/scm/cache/EhCacheConfigurationReader.java
vendored
Normal file
@@ -0,0 +1,475 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Closeables;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import sonia.scm.SCMContext;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class EhCacheConfigurationReader
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String ATTRIBUTE_NAME = "name";
|
||||
|
||||
/** Field description */
|
||||
private static final String DEFAULT = "/config/ehcache.xml";
|
||||
|
||||
/** Field description */
|
||||
private static final String MANUAL_RESOURCE =
|
||||
"ext".concat(File.separator).concat("ehcache.xml");
|
||||
|
||||
/** Field description */
|
||||
private static final String MODULE_RESOURCES = "/META-INF/scm/ehcache.xml";
|
||||
|
||||
/**
|
||||
* the logger for EhCacheConfigurationReader
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(EhCacheConfigurationReader.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public EhCacheConfigurationReader()
|
||||
{
|
||||
try
|
||||
{
|
||||
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
}
|
||||
catch (ParserConfigurationException ex)
|
||||
{
|
||||
throw new RuntimeException("could not create document builder", ex);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public InputStream read()
|
||||
{
|
||||
URL defaultConfig = getDefaultResource();
|
||||
|
||||
if (defaultConfig == null)
|
||||
{
|
||||
throw new IllegalStateException(
|
||||
"could not find default cache configuration");
|
||||
}
|
||||
|
||||
readConfiguration(defaultConfig, true);
|
||||
|
||||
Iterator<URL> it = getModuleResources();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
readConfiguration(it.next(), false);
|
||||
}
|
||||
|
||||
File manualFile = getManualFileResource();
|
||||
|
||||
if (manualFile.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
readConfiguration(manualFile.toURI().toURL(), false);
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
logger.error("malformed url", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("could not find manual configuration at {}", manualFile);
|
||||
}
|
||||
|
||||
Document doc = createMergedConfiguration();
|
||||
|
||||
return createInputStream(doc);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected URL getDefaultResource()
|
||||
{
|
||||
return EhCacheConfigurationReader.class.getResource(DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected File getManualFileResource()
|
||||
{
|
||||
return new File(SCMContext.getContext().getBaseDirectory(),
|
||||
MANUAL_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected Iterator<URL> getModuleResources()
|
||||
{
|
||||
return CacheConfigurations.findModuleResources(
|
||||
EhCacheConfigurationReader.class, MODULE_RESOURCES);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param doc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private InputStream createInputStream(Document doc)
|
||||
{
|
||||
InputStream stream;
|
||||
Transformer transformer;
|
||||
|
||||
try
|
||||
{
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
transformer.transform(new DOMSource(doc), new StreamResult(baos));
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("effective ehcache configuration: {}", baos.toString());
|
||||
}
|
||||
|
||||
stream = new ByteArrayInputStream(baos.toByteArray());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IllegalStateException("could not create transformer", ex);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Document createMergedConfiguration()
|
||||
{
|
||||
Document merged = builder.newDocument();
|
||||
|
||||
Element rootEl = merged.createElementNS("http://ehcache.org/ehcache.xsd",
|
||||
"ehcache");
|
||||
|
||||
for (Attr attribute : attributeMap.values())
|
||||
{
|
||||
Attr mergedAttr = (Attr) merged.adoptNode(attribute);
|
||||
|
||||
rootEl.setAttributeNode(mergedAttr);
|
||||
}
|
||||
|
||||
for (Node node : nodeMap.values())
|
||||
{
|
||||
Node mergedNode = merged.adoptNode(node);
|
||||
|
||||
rootEl.appendChild(mergedNode);
|
||||
}
|
||||
|
||||
merged.appendChild(rootEl);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param url
|
||||
* @param throwException
|
||||
*/
|
||||
private void readConfiguration(URL url, boolean throwException)
|
||||
{
|
||||
logger.debug("read cache configuration from url {}", url.toExternalForm());
|
||||
|
||||
InputStream stream = null;
|
||||
|
||||
try
|
||||
{
|
||||
stream = url.openStream();
|
||||
|
||||
Document document = builder.parse(stream);
|
||||
Element rootEl = document.getDocumentElement();
|
||||
|
||||
readConfiguration(rootEl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (throwException)
|
||||
{
|
||||
throw new RuntimeException(
|
||||
"could not read configuration at ".concat(url.toExternalForm()), ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("could not read configuration at {}", url.toExternalForm());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Closeables.closeQuietly(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param rootEl
|
||||
*/
|
||||
private void readConfiguration(Element rootEl)
|
||||
{
|
||||
NamedNodeMap attributes = rootEl.getAttributes();
|
||||
|
||||
for (int i = 0; i < attributes.getLength(); i++)
|
||||
{
|
||||
Node node = attributes.item(i);
|
||||
|
||||
if (Node.ATTRIBUTE_NODE == node.getNodeType())
|
||||
{
|
||||
String name = node.getNodeName();
|
||||
|
||||
if (!name.startsWith("xmlns") && (node instanceof Attr))
|
||||
{
|
||||
attributeMap.put(node.getNodeName(), (Attr) node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodeList list = rootEl.getChildNodes();
|
||||
|
||||
for (int i = 0; i < list.getLength(); i++)
|
||||
{
|
||||
Node node = list.item(i);
|
||||
|
||||
if (Node.ELEMENT_NODE == node.getNodeType())
|
||||
{
|
||||
String element = node.getNodeName();
|
||||
String name = null;
|
||||
Node nameNode = node.getAttributes().getNamedItem(ATTRIBUTE_NAME);
|
||||
|
||||
if (nameNode != null)
|
||||
{
|
||||
name = nameNode.getNodeValue();
|
||||
}
|
||||
|
||||
nodeMap.put(new Id(element, name), node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 13/03/19
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class Id
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param element
|
||||
* @param name
|
||||
*/
|
||||
public Id(String element, String name)
|
||||
{
|
||||
this.element = element;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Id other = (Id) obj;
|
||||
|
||||
return Objects.equal(element, other.element)
|
||||
&& Objects.equal(name, other.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(element, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("element", element)
|
||||
.add("name", name)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String element;
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private DocumentBuilder builder;
|
||||
|
||||
/** Field description */
|
||||
private Map<Id, Node> nodeMap = Maps.newLinkedHashMap();
|
||||
|
||||
/** Field description */
|
||||
private Map<String, Attr> attributeMap = Maps.newLinkedHashMap();
|
||||
}
|
||||
@@ -35,6 +35,7 @@ package sonia.scm.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.io.Closeables;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -43,6 +44,7 @@ import org.slf4j.LoggerFactory;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -67,8 +69,20 @@ public class EhCacheManager implements CacheManager
|
||||
*/
|
||||
public EhCacheManager()
|
||||
{
|
||||
cacheManager =
|
||||
new net.sf.ehcache.CacheManager(EhCacheManager.class.getResource(CONFIG));
|
||||
|
||||
InputStream stream = null;
|
||||
|
||||
try
|
||||
{
|
||||
EhCacheConfigurationReader reader = new EhCacheConfigurationReader();
|
||||
|
||||
stream = reader.read();
|
||||
cacheManager = new net.sf.ehcache.CacheManager(stream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Closeables.closeQuietly(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +125,8 @@ public class EhCacheManager implements CacheManager
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public <K, V> Cache<K, V> getCache(Class<K> key, Class<V> value, String name)
|
||||
public synchronized <K, V> Cache<K, V> getCache(Class<K> key, Class<V> value,
|
||||
String name)
|
||||
{
|
||||
net.sf.ehcache.Cache c = cacheManager.getCache(name);
|
||||
|
||||
|
||||
236
scm-webapp/src/main/java/sonia/scm/cache/GuavaCache.java
vendored
Normal file
236
scm-webapp/src/main/java/sonia/scm/cache/GuavaCache.java
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.Filter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
*/
|
||||
public class GuavaCache<K, V> implements Cache<K, V>
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for GuavaCache
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(GuavaCache.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
*/
|
||||
public GuavaCache(GuavaNamedCacheConfiguration configuration)
|
||||
{
|
||||
this(configuration, configuration.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param name
|
||||
*/
|
||||
public GuavaCache(GuavaCacheConfiguration configuration, String name)
|
||||
{
|
||||
this(GuavaCaches.create(configuration, name),
|
||||
configuration.getCopyStrategy(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param cache
|
||||
* @param copyStrategy
|
||||
* @param name
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected GuavaCache(com.google.common.cache.Cache<K, V> cache,
|
||||
CopyStrategy copyStrategy, String name)
|
||||
{
|
||||
this.cache = cache;
|
||||
this.name = name;
|
||||
|
||||
if (copyStrategy != null)
|
||||
{
|
||||
this.copyStrategy = copyStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("clear cache {}", name);
|
||||
}
|
||||
|
||||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(K key)
|
||||
{
|
||||
return cache.getIfPresent(key) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
@Override
|
||||
public void put(K key, V value)
|
||||
{
|
||||
cache.put(key, copyStrategy.copyOnWrite(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean remove(K key)
|
||||
{
|
||||
cache.invalidate(key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param filter
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean removeAll(Filter<K> filter)
|
||||
{
|
||||
Set<K> keysToRemove = Sets.newHashSet();
|
||||
|
||||
for (K key : cache.asMap().keySet())
|
||||
{
|
||||
if (filter.accept(key))
|
||||
{
|
||||
keysToRemove.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
boolean result = false;
|
||||
|
||||
if (!keysToRemove.isEmpty())
|
||||
{
|
||||
cache.invalidateAll(keysToRemove);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public V get(K key)
|
||||
{
|
||||
V value = cache.getIfPresent(key);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
value = copyStrategy.copyOnRead(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private com.google.common.cache.Cache<K, V> cache;
|
||||
|
||||
/** Field description */
|
||||
private CopyStrategy copyStrategy = CopyStrategy.NONE;
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
}
|
||||
223
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheConfiguration.java
vendored
Normal file
223
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheConfiguration.java
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@XmlRootElement(name = "cache")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class GuavaCacheConfiguration implements Serializable
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -8734373158089010603L;
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Integer getConcurrencyLevel()
|
||||
{
|
||||
return concurrencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CopyStrategy getCopyStrategy()
|
||||
{
|
||||
return copyStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getExpireAfterAccess()
|
||||
{
|
||||
return expireAfterAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getExpireAfterWrite()
|
||||
{
|
||||
return expireAfterWrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Integer getInitialCapacity()
|
||||
{
|
||||
return initialCapacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getMaximumSize()
|
||||
{
|
||||
return maximumSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getMaximumWeight()
|
||||
{
|
||||
return maximumWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Boolean getRecordStats()
|
||||
{
|
||||
return recordStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Boolean getSoftValues()
|
||||
{
|
||||
return softValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Boolean getWeakKeys()
|
||||
{
|
||||
return weakKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Boolean getWeakValues()
|
||||
{
|
||||
return weakValues;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Integer concurrencyLevel;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private CopyStrategy copyStrategy;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Long expireAfterAccess;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Long expireAfterWrite;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Integer initialCapacity;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Long maximumSize;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Long maximumWeight;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Boolean recordStats;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Boolean softValues;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Boolean weakKeys;
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private Boolean weakValues;
|
||||
}
|
||||
308
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheConfigurationReader.java
vendored
Normal file
308
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheConfigurationReader.java
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.SCMContext;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class GuavaCacheConfigurationReader
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String DEFAULT = "/config/gcache.xml";
|
||||
|
||||
/** Field description */
|
||||
private static final String MANUAL_RESOURCE =
|
||||
"ext".concat(File.separator).concat("gcache.xml");
|
||||
|
||||
/** Field description */
|
||||
private static final String MODULE_RESOURCES = "/META-INF/scm/gcache.xml";
|
||||
|
||||
/**
|
||||
* the logger for CacheConfigurationReader
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(GuavaCacheConfigurationReader.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private GuavaCacheConfigurationReader()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.context =
|
||||
JAXBContext.newInstance(GuavaCacheManagerConfiguration.class);
|
||||
}
|
||||
catch (JAXBException ex)
|
||||
{
|
||||
throw new CacheException(
|
||||
"could not create jaxb context for cache configuration", ex);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GuavaCacheManagerConfiguration read()
|
||||
{
|
||||
return new GuavaCacheConfigurationReader().doRead();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected URL getDefaultResource()
|
||||
{
|
||||
return GuavaCacheConfigurationReader.class.getResource(DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected File getManualFileResource()
|
||||
{
|
||||
return new File(SCMContext.getContext().getBaseDirectory(),
|
||||
MANUAL_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected Iterator<URL> getModuleResources()
|
||||
{
|
||||
return CacheConfigurations.findModuleResources(
|
||||
EhCacheConfigurationReader.class, MODULE_RESOURCES);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param caches
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Map<String, GuavaNamedCacheConfiguration> createNamedCacheMap(
|
||||
List<GuavaNamedCacheConfiguration> caches)
|
||||
{
|
||||
Map<String, GuavaNamedCacheConfiguration> map = Maps.newLinkedHashMap();
|
||||
|
||||
for (GuavaNamedCacheConfiguration ncc : caches)
|
||||
{
|
||||
map.put(ncc.getName(), ncc);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private GuavaCacheManagerConfiguration doRead()
|
||||
{
|
||||
URL defaultConfigUrl = getDefaultResource();
|
||||
|
||||
if (defaultConfigUrl == null)
|
||||
{
|
||||
throw new IllegalStateException(
|
||||
"could not find default cache configuration");
|
||||
}
|
||||
|
||||
GuavaCacheManagerConfiguration config = readConfiguration(defaultConfigUrl,
|
||||
true);
|
||||
|
||||
Iterator<URL> it = getModuleResources();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
GuavaCacheManagerConfiguration moduleConfig =
|
||||
readConfiguration(it.next(), false);
|
||||
|
||||
if (moduleConfig != null)
|
||||
{
|
||||
config = merge(config, moduleConfig);
|
||||
}
|
||||
}
|
||||
|
||||
File manualFile = getManualFileResource();
|
||||
|
||||
if (manualFile.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
GuavaCacheManagerConfiguration manualConfig =
|
||||
readConfiguration(manualFile.toURI().toURL(), false);
|
||||
|
||||
config = merge(config, manualConfig);
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
logger.error("malformed url", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("could not find manual configuration at {}", manualFile);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
* @param other
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private GuavaCacheManagerConfiguration merge(
|
||||
GuavaCacheManagerConfiguration config, GuavaCacheManagerConfiguration other)
|
||||
{
|
||||
GuavaCacheConfiguration defaultCache = config.getDefaultCache();
|
||||
Map<String, GuavaNamedCacheConfiguration> namedCaches =
|
||||
createNamedCacheMap(config.getCaches());
|
||||
|
||||
if (other.getDefaultCache() != null)
|
||||
{
|
||||
defaultCache = other.getDefaultCache();
|
||||
}
|
||||
|
||||
List<GuavaNamedCacheConfiguration> otherNamedCaches = other.getCaches();
|
||||
|
||||
for (GuavaNamedCacheConfiguration ncc : otherNamedCaches)
|
||||
{
|
||||
namedCaches.put(ncc.getName(), ncc);
|
||||
}
|
||||
|
||||
return new GuavaCacheManagerConfiguration(defaultCache,
|
||||
ImmutableList.copyOf(namedCaches.values()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param url
|
||||
* @param fail
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private GuavaCacheManagerConfiguration readConfiguration(URL url,
|
||||
boolean fail)
|
||||
{
|
||||
GuavaCacheManagerConfiguration config = null;
|
||||
|
||||
try
|
||||
{
|
||||
config =
|
||||
(GuavaCacheManagerConfiguration) context.createUnmarshaller().unmarshal(
|
||||
url);
|
||||
}
|
||||
catch (JAXBException ex)
|
||||
{
|
||||
if (fail)
|
||||
{
|
||||
throw new CacheException("could not unmarshall cache configuration",
|
||||
ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("could not unmarshall cache configuration", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private JAXBContext context;
|
||||
}
|
||||
153
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java
vendored
Normal file
153
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Singleton
|
||||
public class GuavaCacheManager implements CacheManager
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for GuavaCacheManager
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(GuavaCacheManager.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public GuavaCacheManager()
|
||||
{
|
||||
this(GuavaCacheConfigurationReader.read());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected GuavaCacheManager(GuavaCacheManagerConfiguration config)
|
||||
{
|
||||
defaultConfiguration = config.getDefaultCache();
|
||||
|
||||
for (GuavaNamedCacheConfiguration ncc : config.getCaches())
|
||||
{
|
||||
cacheMap.put(ncc.getName(), new GuavaCache(ncc));
|
||||
}
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
logger.info("close guava cache manager");
|
||||
|
||||
for (Cache c : cacheMap.values())
|
||||
{
|
||||
c.clear();
|
||||
}
|
||||
|
||||
cacheMap.clear();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param name
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public synchronized <K, V> GuavaCache<K, V> getCache(Class<K> key,
|
||||
Class<V> value, String name)
|
||||
{
|
||||
logger.trace("try to retrieve cache {}", name);
|
||||
|
||||
GuavaCache<K, V> cache = cacheMap.get(name);
|
||||
|
||||
if (cache == null)
|
||||
{
|
||||
logger.debug(
|
||||
"cache {} does not exists, creating a new instance from default configuration: {}",
|
||||
name, defaultConfiguration);
|
||||
cache = new GuavaCache<K, V>(defaultConfiguration, name);
|
||||
cacheMap.put(name, cache);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private volatile Map<String, GuavaCache> cacheMap = Maps.newHashMap();
|
||||
|
||||
/** Field description */
|
||||
private GuavaCacheConfiguration defaultConfiguration;
|
||||
}
|
||||
111
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManagerConfiguration.java
vendored
Normal file
111
scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManagerConfiguration.java
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
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 = "caches")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class GuavaCacheManagerConfiguration
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public GuavaCacheManagerConfiguration() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param defaultCache
|
||||
* @param caches
|
||||
*/
|
||||
public GuavaCacheManagerConfiguration(GuavaCacheConfiguration defaultCache,
|
||||
List<GuavaNamedCacheConfiguration> caches)
|
||||
{
|
||||
this.defaultCache = defaultCache;
|
||||
this.caches = caches;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<GuavaNamedCacheConfiguration> getCaches()
|
||||
{
|
||||
if (caches == null)
|
||||
{
|
||||
caches = Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return caches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public GuavaCacheConfiguration getDefaultCache()
|
||||
{
|
||||
return defaultCache;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "cache")
|
||||
private List<GuavaNamedCacheConfiguration> caches;
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "defaultCache")
|
||||
private GuavaCacheConfiguration defaultCache;
|
||||
}
|
||||
156
scm-webapp/src/main/java/sonia/scm/cache/GuavaCaches.java
vendored
Normal file
156
scm-webapp/src/main/java/sonia/scm/cache/GuavaCaches.java
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public final class GuavaCaches
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for GuavaCaches
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(GuavaCaches.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private GuavaCaches() {}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static com.google.common.cache.Cache create(
|
||||
GuavaCacheConfiguration configuration, String name)
|
||||
{
|
||||
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
|
||||
|
||||
if (configuration.getConcurrencyLevel() != null)
|
||||
{
|
||||
builder.concurrencyLevel(configuration.getConcurrencyLevel());
|
||||
}
|
||||
|
||||
if (configuration.getExpireAfterAccess() != null)
|
||||
{
|
||||
builder.expireAfterAccess(configuration.getExpireAfterAccess(),
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
if (configuration.getExpireAfterWrite() != null)
|
||||
{
|
||||
builder.expireAfterWrite(configuration.getExpireAfterWrite(),
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
if (configuration.getInitialCapacity() != null)
|
||||
{
|
||||
builder.initialCapacity(configuration.getInitialCapacity());
|
||||
}
|
||||
|
||||
if (configuration.getMaximumSize() != null)
|
||||
{
|
||||
builder.maximumSize(configuration.getMaximumSize());
|
||||
}
|
||||
|
||||
if (configuration.getMaximumWeight() != null)
|
||||
{
|
||||
builder.maximumWeight(configuration.getMaximumWeight());
|
||||
}
|
||||
|
||||
if (isEnabled(configuration.getRecordStats()))
|
||||
{
|
||||
builder.recordStats();
|
||||
}
|
||||
|
||||
if (isEnabled(configuration.getSoftValues()))
|
||||
{
|
||||
builder.softValues();
|
||||
}
|
||||
|
||||
if (isEnabled(configuration.getWeakKeys()))
|
||||
{
|
||||
builder.weakKeys();
|
||||
}
|
||||
|
||||
if (isEnabled(configuration.getWeakValues()))
|
||||
{
|
||||
builder.weakKeys();
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("create new cache {} from builder: {}", name, builder);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param v
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static boolean isEnabled(Boolean v)
|
||||
{
|
||||
return (v != null) && v;
|
||||
}
|
||||
}
|
||||
71
scm-webapp/src/main/java/sonia/scm/cache/GuavaNamedCacheConfiguration.java
vendored
Normal file
71
scm-webapp/src/main/java/sonia/scm/cache/GuavaNamedCacheConfiguration.java
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@XmlRootElement(name = "cache")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class GuavaNamedCacheConfiguration extends GuavaCacheConfiguration
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -624795324874828475L;
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlAttribute
|
||||
private String name;
|
||||
}
|
||||
@@ -37,6 +37,7 @@ package sonia.scm.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
@@ -139,7 +140,11 @@ public class SearchHandler<T>
|
||||
Collections2.transform(users, function);
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResults(resultCollection);
|
||||
|
||||
// create a copy of the result collection to reduce memory
|
||||
// use ArrayList instead of ImmutableList for copy,
|
||||
// because the list must be mutable for decorators
|
||||
result.setResults(Lists.newArrayList(resultCollection));
|
||||
cache.put(queryString, result);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user