mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 17:26:22 +01:00
merge with branch issue-345
This commit is contained in:
95
scm-core/src/main/java/sonia/scm/io/DeepCopy.java
Normal file
95
scm-core/src/main/java/sonia/scm/io/DeepCopy.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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.io;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* Utility for making deep copies (vs. clone()'s shallow copies) of
|
||||
* objects. Objects are first serialized and then deserialized. Error
|
||||
* checking is fairly minimal in this implementation. If an object is
|
||||
* encountered that cannot be serialized (or that references an object
|
||||
* that cannot be serialized) an error is printed to System.err and
|
||||
* null is returned. Depending on your specific application, it might
|
||||
* make more sense to have copy(...) re-throw the exception.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.29
|
||||
* @see http://javatechniques.com/blog/faster-deep-copies-of-java-objects
|
||||
*/
|
||||
public final class DeepCopy
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a copy of the object, or null if the object cannot
|
||||
* be serialized.
|
||||
*
|
||||
* @param orig
|
||||
* @param <T>
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static <T> T copy(T orig) throws IOException
|
||||
{
|
||||
T obj = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Write the object out to a byte array
|
||||
FastByteArrayOutputStream fbos = new FastByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(fbos);
|
||||
|
||||
out.writeObject(orig);
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
// Retrieve an input stream from the byte array and read
|
||||
// a copy of the object back in.
|
||||
ObjectInputStream in = new ObjectInputStream(fbos.getInputStream());
|
||||
|
||||
obj = (T) in.readObject();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException("could not copy object", ex);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 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.io;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* ByteArrayInputStream implementation that does not synchronize methods.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.29
|
||||
* @see http://javatechniques.com/blog/faster-deep-copies-of-java-objects
|
||||
*/
|
||||
public final class FastByteArrayInputStream extends InputStream
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param buf
|
||||
* @param count
|
||||
*/
|
||||
public FastByteArrayInputStream(byte[] buf, int count)
|
||||
{
|
||||
this.buf = buf;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final int available()
|
||||
{
|
||||
return count - pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final int read()
|
||||
{
|
||||
return (pos < count)
|
||||
? (buf[pos++] & 0xff)
|
||||
: -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param b
|
||||
* @param off
|
||||
* @param len
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final int read(byte[] b, int off, int len)
|
||||
{
|
||||
if (pos >= count)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((pos + len) > count)
|
||||
{
|
||||
len = (count - pos);
|
||||
}
|
||||
|
||||
System.arraycopy(buf, pos, b, off, len);
|
||||
pos += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param n
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final long skip(long n)
|
||||
{
|
||||
if ((pos + n) > count)
|
||||
{
|
||||
n = count - pos;
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos += n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Our byte buffer
|
||||
*/
|
||||
private byte[] buf = null;
|
||||
|
||||
/**
|
||||
* Number of bytes that we can read from the buffer
|
||||
*/
|
||||
private int count = 0;
|
||||
|
||||
/**
|
||||
* Number of bytes that have been read from the buffer
|
||||
*/
|
||||
private int pos = 0;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* 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.io;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* ByteArrayOutputStream implementation that doesn't synchronize methods
|
||||
* and doesn't copy the data on toByteArray().
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.29
|
||||
* @see http://javatechniques.com/blog/faster-deep-copies-of-java-objects
|
||||
*/
|
||||
public final class FastByteArrayOutputStream extends OutputStream
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a stream with buffer capacity size 5K
|
||||
*/
|
||||
public FastByteArrayOutputStream()
|
||||
{
|
||||
this(5 * 1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a stream with the given initial size
|
||||
*
|
||||
* @param initSize
|
||||
*/
|
||||
public FastByteArrayOutputStream(int initSize)
|
||||
{
|
||||
this.size = 0;
|
||||
this.buf = new byte[initSize];
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param b
|
||||
*/
|
||||
@Override
|
||||
public final void write(byte b[])
|
||||
{
|
||||
verifyBufferSize(size + b.length);
|
||||
System.arraycopy(b, 0, buf, size, b.length);
|
||||
size += b.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param b
|
||||
* @param off
|
||||
* @param len
|
||||
*/
|
||||
@Override
|
||||
public final void write(byte b[], int off, int len)
|
||||
{
|
||||
verifyBufferSize(size + len);
|
||||
System.arraycopy(b, off, buf, size, len);
|
||||
size += len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param b
|
||||
*/
|
||||
@Override
|
||||
public final void write(int b)
|
||||
{
|
||||
verifyBufferSize(size + 1);
|
||||
buf[size++] = (byte) b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the byte array containing the written data. Note that this
|
||||
* array will almost always be larger than the amount of data actually
|
||||
* written.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] getByteArray()
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ByteArrayInputStream for reading back the written data
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public InputStream getInputStream()
|
||||
{
|
||||
return new FastByteArrayInputStream(buf, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Ensures that we have a large enough buffer for the given size.
|
||||
*
|
||||
* @param sz
|
||||
*/
|
||||
private void verifyBufferSize(int sz)
|
||||
{
|
||||
if (sz > buf.length)
|
||||
{
|
||||
byte[] old = buf;
|
||||
|
||||
buf = new byte[Math.max(sz, 2 * buf.length)];
|
||||
System.arraycopy(old, 0, buf, 0, old.length);
|
||||
old = null;
|
||||
}
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Buffer and size
|
||||
*/
|
||||
private byte[] buf = null;
|
||||
|
||||
/** Field description */
|
||||
private int size = 0;
|
||||
}
|
||||
@@ -33,6 +33,10 @@
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -83,6 +87,45 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final ChangesetPagingResult other = (ChangesetPagingResult) obj;
|
||||
|
||||
return Objects.equal(changesets, other.changesets)
|
||||
&& Objects.equal(total, other.total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(changesets, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator which can iterate over the current list of changesets.
|
||||
*
|
||||
@@ -103,6 +146,23 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("changesets", changesets)
|
||||
.add("total", total)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,11 +77,14 @@ public final class LogCommandRequest implements Serializable, Resetable
|
||||
|
||||
final LogCommandRequest other = (LogCommandRequest) obj;
|
||||
|
||||
//J-
|
||||
return Objects.equal(startChangeset, other.startChangeset)
|
||||
&& Objects.equal(endChangeset, other.endChangeset)
|
||||
&& Objects.equal(pagingStart, other.pagingStart)
|
||||
&& Objects.equal(pagingLimit, other.pagingLimit)
|
||||
&& Objects.equal(path, other.path) && Objects.equal(branch, other.branch);
|
||||
&& Objects.equal(path, other.path)
|
||||
&& Objects.equal(branch, other.branch);
|
||||
//J+
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -212,9 +212,10 @@ public class GitChangesetConverter implements Closeable
|
||||
|
||||
Collection<String> tagCollection = tags.get(commit.getId());
|
||||
|
||||
if (tagCollection != null)
|
||||
if (Util.isNotEmpty(tagCollection))
|
||||
{
|
||||
changeset.getTags().addAll(tagCollection);
|
||||
// create a copy of the tag collection to reduce memory on caching
|
||||
changeset.getTags().addAll(Lists.newArrayList(tagCollection));
|
||||
}
|
||||
|
||||
changeset.setBranches(branches);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
Purpose of the document follows.
|
||||
-->
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd"
|
||||
updateCheck="false"
|
||||
maxBytesLocalDisk="512M">
|
||||
|
||||
|
||||
<!--
|
||||
@@ -88,18 +90,23 @@
|
||||
-->
|
||||
|
||||
<defaultCache
|
||||
maxElementsInMemory="20000"
|
||||
maxEntriesLocalHeap="100"
|
||||
maxEntriesLocalDisk="10000"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
overflowToDisk="true"
|
||||
timeToIdleSeconds="1200"
|
||||
timeToLiveSeconds="2400"
|
||||
diskPersistent="false"
|
||||
diskExpiryThreadIntervalSeconds="2400"
|
||||
diskExpiryThreadIntervalSeconds="120"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Authentication cache
|
||||
average: 1K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.auth"
|
||||
maxElementsInMemory="200000"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="30"
|
||||
@@ -107,38 +114,135 @@
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Authorization cache
|
||||
average: 3K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.authorizing"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="1200"
|
||||
timeToLiveSeconds="2400"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!--
|
||||
PluginCenter cache
|
||||
average: 30K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.plugins"
|
||||
maxElementsInMemory="10"
|
||||
maxEntriesLocalHeap="5"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToLiveSeconds="3600"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Search cache for users
|
||||
average: 0.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.search.users"
|
||||
maxElementsInMemory="10000"
|
||||
maxEntriesLocalHeap="10000"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToLiveSeconds="5400"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Search cache for groups
|
||||
average: 0.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.search.groups"
|
||||
maxElementsInMemory="1000"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToLiveSeconds="5400"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!-- old repository api -->
|
||||
<!-- new repository api -->
|
||||
|
||||
<!--
|
||||
Changeset cache
|
||||
average: 25K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.log"
|
||||
maxEntriesLocalHeap="200"
|
||||
maxEntriesLocalDisk="10000"
|
||||
eternal="true"
|
||||
overflowToDisk="true"
|
||||
diskPersistent="false"
|
||||
copyOnRead="true"
|
||||
copyOnWrite="true"
|
||||
/>
|
||||
|
||||
<!--
|
||||
FileObject cache
|
||||
average: 1.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.browse"
|
||||
maxEntriesLocalHeap="3000"
|
||||
maxEntriesLocalDisk="20000"
|
||||
eternal="true"
|
||||
overflowToDisk="true"
|
||||
diskPersistent="false"
|
||||
copyOnRead="true"
|
||||
copyOnWrite="true"
|
||||
/>
|
||||
|
||||
<!--
|
||||
BlameResult cache
|
||||
average: 15K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.blame"
|
||||
maxEntriesLocalHeap="1000"
|
||||
maxEntriesLocalDisk="10000"
|
||||
eternal="true"
|
||||
overflowToDisk="true"
|
||||
diskPersistent="false"
|
||||
copyOnRead="true"
|
||||
copyOnWrite="true"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Tag cache
|
||||
average: 5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.tags"
|
||||
maxEntriesLocalHeap="500"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Branch cache
|
||||
average: 2.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.branches"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!-- deprecated old repository api -->
|
||||
|
||||
<cache
|
||||
name="sonia.cache.repository.changesets"
|
||||
maxElementsInMemory="20000"
|
||||
maxEntriesLocalHeap="200"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToLiveSeconds="86400"
|
||||
@@ -147,7 +251,7 @@
|
||||
|
||||
<cache
|
||||
name="sonia.cache.repository.browser"
|
||||
maxElementsInMemory="10000"
|
||||
maxEntriesLocalHeap="200"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToLiveSeconds="86400"
|
||||
@@ -156,59 +260,11 @@
|
||||
|
||||
<cache
|
||||
name="sonia.cache.repository.blame"
|
||||
maxElementsInMemory="1000"
|
||||
maxEntriesLocalHeap="100"
|
||||
eternal="false"
|
||||
overflowToDisk="false"
|
||||
timeToLiveSeconds="86400"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<!-- new repository api -->
|
||||
|
||||
<cache
|
||||
name="sonia.cache.cmd.log"
|
||||
maxElementsInMemory="20000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
copyOnRead="true"
|
||||
copyOnWrite="true"
|
||||
/>
|
||||
|
||||
<cache
|
||||
name="sonia.cache.cmd.browse"
|
||||
maxElementsInMemory="10000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
copyOnRead="true"
|
||||
copyOnWrite="true"
|
||||
/>
|
||||
|
||||
<cache
|
||||
name="sonia.cache.cmd.blame"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
copyOnRead="true"
|
||||
copyOnWrite="true"
|
||||
/>
|
||||
|
||||
<cache
|
||||
name="sonia.cache.cmd.tags"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
<cache
|
||||
name="sonia.cache.cmd.branches"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
/>
|
||||
|
||||
</ehcache>
|
||||
|
||||
145
scm-webapp/src/main/resources/config/gcache.xml
Normal file
145
scm-webapp/src/main/resources/config/gcache.xml
Normal file
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<caches>
|
||||
|
||||
<defaultCache
|
||||
maximumSize="200"
|
||||
expireAfterAccess="1200"
|
||||
expireAfterWrite="2400"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Authentication cache
|
||||
average: 1K
|
||||
-->
|
||||
|
||||
<cache
|
||||
name="sonia.cache.auth"
|
||||
maximumSize="1000"
|
||||
expireAfterAccess="30"
|
||||
expireAfterWrite="60"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Authorization cache
|
||||
average: 3K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.authorizing"
|
||||
maximumSize="1000"
|
||||
expireAfterAccess="1200"
|
||||
expireAfterWrite="2400"
|
||||
/>
|
||||
|
||||
<!--
|
||||
PluginCenter cache
|
||||
average: 30K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.plugins"
|
||||
maximumSize="5"
|
||||
expireAfterWrite="3600"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Search cache for users
|
||||
average: 0.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.search.users"
|
||||
maximumSize="10000"
|
||||
expireAfterWrite="5400"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Search cache for groups
|
||||
average: 0.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.search.groups"
|
||||
maximumSize="1000"
|
||||
expireAfterWrite="5400"
|
||||
/>
|
||||
|
||||
<!-- new repository api -->
|
||||
|
||||
<!--
|
||||
Changeset cache
|
||||
average: 25K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.log"
|
||||
maximumSize="500"
|
||||
copyStrategy="read-write"
|
||||
/>
|
||||
|
||||
<!--
|
||||
FileObject cache
|
||||
average: 1.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.browse"
|
||||
maximumSize="3000"
|
||||
copyStrategy="read-write"
|
||||
/>
|
||||
|
||||
<!--
|
||||
BlameResult cache
|
||||
average: 15K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.blame"
|
||||
maximumSize="1000"
|
||||
copyStrategy="read-write"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Tag cache
|
||||
average: 5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.tags"
|
||||
maximumSize="500"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Branch cache
|
||||
average: 2.5K
|
||||
-->
|
||||
<cache
|
||||
name="sonia.cache.cmd.branches"
|
||||
maximumSize="500"
|
||||
/>
|
||||
|
||||
</caches>
|
||||
@@ -77,6 +77,11 @@
|
||||
<logger name="com.aragost.javahg" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<!-- ehcache -->
|
||||
<!--
|
||||
<logger name="net.sf.ehcache" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
@@ -99,6 +99,11 @@
|
||||
<logger name="com.aragost.javahg" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<!-- ehcache -->
|
||||
<!--
|
||||
<logger name="net.sf.ehcache" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="STDOUT" />
|
||||
|
||||
224
scm-webapp/src/test/java/sonia/scm/cache/CacheManagerTestBase.java
vendored
Normal file
224
scm-webapp/src/test/java/sonia/scm/cache/CacheManagerTestBase.java
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* 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.Sets;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*
|
||||
* @param <C>
|
||||
*/
|
||||
public abstract class CacheManagerTestBase<C extends Cache>
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract CacheManager createCacheManager();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws IOException
|
||||
{
|
||||
cacheManager.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testSameReference()
|
||||
{
|
||||
Cache<String, String> c1 = cacheManager.getCache(String.class,
|
||||
String.class, "test-1");
|
||||
Cache<String, String> c2 = cacheManager.getCache(String.class,
|
||||
String.class, "test-1");
|
||||
|
||||
assertIsSame(c1, c2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws ExecutionException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testSameReferenceMultiThreaded()
|
||||
throws InterruptedException, ExecutionException
|
||||
{
|
||||
ExecutorService executor = Executors.newFixedThreadPool(2);
|
||||
|
||||
Set<Future<Cache>> caches = Sets.newHashSet();
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
//J-
|
||||
caches.add(
|
||||
executor.submit(new AcquireCacheCallable(cacheManager, "test-2"))
|
||||
);
|
||||
//J+
|
||||
}
|
||||
|
||||
executor.shutdown();
|
||||
|
||||
Cache c = null;
|
||||
|
||||
for (Future<Cache> f : caches)
|
||||
{
|
||||
Cache nc = f.get();
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
assertIsSame(c, nc);
|
||||
}
|
||||
|
||||
c = nc;
|
||||
}
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
cacheManager = createCacheManager();
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param c1
|
||||
* @param c2
|
||||
*/
|
||||
protected void assertIsSame(Cache<String, String> c1,
|
||||
Cache<String, String> c2)
|
||||
{
|
||||
assertSame(c1, c2);
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 13/03/25
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class AcquireCacheCallable implements Callable<Cache>
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param cacheManager
|
||||
* @param name
|
||||
*/
|
||||
public AcquireCacheCallable(CacheManager cacheManager, String name)
|
||||
{
|
||||
this.cacheManager = cacheManager;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public Cache call() throws Exception
|
||||
{
|
||||
return cacheManager.getCache(String.class, String.class, name);
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private CacheManager cacheManager;
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private CacheManager cacheManager;
|
||||
}
|
||||
165
scm-webapp/src/test/java/sonia/scm/cache/CacheTestBase.java
vendored
Normal file
165
scm-webapp/src/test/java/sonia/scm/cache/CacheTestBase.java
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* 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 org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import sonia.scm.Filter;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public abstract class CacheTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract CacheManager createCacheManager();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@After
|
||||
public void after()
|
||||
{
|
||||
IOUtil.close(cm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
cm = createCacheManager();
|
||||
cache = cm.getCache(String.class, String.class, "test");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testClear()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
cache.put("test-1", "test123");
|
||||
cache.clear();
|
||||
assertNull(cache.get("test"));
|
||||
assertNull(cache.get("test-1"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testContains()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
cache.put("test-1", "test123");
|
||||
assertTrue(cache.contains("test"));
|
||||
assertTrue(cache.contains("test-1"));
|
||||
assertFalse(cache.contains("test-2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testPutAndGet()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
assertEquals("test123", cache.get("test"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testRemove()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
assertEquals("test123", cache.get("test"));
|
||||
cache.remove("test");
|
||||
assertNull(cache.get("test"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveAll()
|
||||
{
|
||||
cache.put("test-1", "test123");
|
||||
cache.put("test-2", "test123");
|
||||
cache.put("a-1", "test123");
|
||||
cache.put("a-2", "test123");
|
||||
cache.removeAll(new Filter<String>()
|
||||
{
|
||||
@Override
|
||||
public boolean accept(String item)
|
||||
{
|
||||
return item.startsWith("test");
|
||||
}
|
||||
});
|
||||
assertNull(cache.get("test-1"));
|
||||
assertNull(cache.get("test-2"));
|
||||
assertNotNull(cache.get("a-1"));
|
||||
assertNotNull(cache.get("a-2"));
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private Cache<String, String> cache;
|
||||
|
||||
/** Field description */
|
||||
private CacheManager cm;
|
||||
}
|
||||
77
scm-webapp/src/test/java/sonia/scm/cache/CacheTestUtil.java
vendored
Normal file
77
scm-webapp/src/test/java/sonia/scm/cache/CacheTestUtil.java
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public final class CacheTestUtil
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private CacheTestUtil() {}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static EhCacheManager createDefaultEhCacheManager()
|
||||
{
|
||||
return new EhCacheManager(net.sf.ehcache.CacheManager.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static GuavaCacheManager createDefaultGuavaCacheManager()
|
||||
{
|
||||
GuavaCacheConfiguration config = new GuavaCacheConfiguration();
|
||||
|
||||
return new GuavaCacheManager(new GuavaCacheManagerConfiguration(config,
|
||||
Collections.EMPTY_LIST));
|
||||
}
|
||||
}
|
||||
84
scm-webapp/src/test/java/sonia/scm/cache/EhCacheManagerTest.java
vendored
Normal file
84
scm-webapp/src/test/java/sonia/scm/cache/EhCacheManagerTest.java
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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 org.junit.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class EhCacheManagerTest extends CacheManagerTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param c1
|
||||
* @param c2
|
||||
*/
|
||||
@Override
|
||||
protected void assertIsSame(Cache c1, Cache c2)
|
||||
{
|
||||
Assert.assertSame(getCacheImplementation(c1), getCacheImplementation(c1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected CacheManager createCacheManager()
|
||||
{
|
||||
return CacheTestUtil.createDefaultEhCacheManager();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param c1
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private net.sf.ehcache.Cache getCacheImplementation(Cache c1)
|
||||
{
|
||||
return ((EhCache) c1).getCacheImplementation();
|
||||
}
|
||||
}
|
||||
@@ -33,127 +33,22 @@
|
||||
|
||||
package sonia.scm.cache;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import sonia.scm.Filter;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class EhCacheTest
|
||||
public class EhCacheTest extends CacheTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@After
|
||||
public void after()
|
||||
{
|
||||
IOUtil.close(cm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
cm = new EhCacheManager(net.sf.ehcache.CacheManager.create());
|
||||
cache = cm.getCache(String.class, String.class, "test");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testClear()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
cache.put("test-1", "test123");
|
||||
cache.clear();
|
||||
assertNull(cache.get("test"));
|
||||
assertNull(cache.get("test-1"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testContains()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
cache.put("test-1", "test123");
|
||||
assertTrue(cache.contains("test"));
|
||||
assertTrue(cache.contains("test-1"));
|
||||
assertFalse(cache.contains("test-2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testPutAndGet()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
assertEquals("test123", cache.get("test"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testRemove()
|
||||
{
|
||||
cache.put("test", "test123");
|
||||
assertEquals("test123", cache.get("test"));
|
||||
cache.remove("test");
|
||||
assertNull(cache.get("test"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveAll()
|
||||
{
|
||||
cache.put("test-1", "test123");
|
||||
cache.put("test-2", "test123");
|
||||
cache.put("a-1", "test123");
|
||||
cache.put("a-2", "test123");
|
||||
cache.removeAll(new Filter<String>()
|
||||
{
|
||||
@Override
|
||||
public boolean accept(String item)
|
||||
protected CacheManager createCacheManager()
|
||||
{
|
||||
return item.startsWith("test");
|
||||
return CacheTestUtil.createDefaultEhCacheManager();
|
||||
}
|
||||
});
|
||||
assertNull(cache.get("test-1"));
|
||||
assertNull(cache.get("test-2"));
|
||||
assertNotNull(cache.get("a-1"));
|
||||
assertNotNull(cache.get("a-2"));
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private Cache<String, String> cache;
|
||||
|
||||
/** Field description */
|
||||
private CacheManager cm;
|
||||
}
|
||||
|
||||
464
scm-webapp/src/test/java/sonia/scm/cache/EhConfigurationReaderTest.java
vendored
Normal file
464
scm-webapp/src/test/java/sonia/scm/cache/EhConfigurationReaderTest.java
vendored
Normal file
@@ -0,0 +1,464 @@
|
||||
/**
|
||||
* 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.base.Function;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.io.Closeables;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import net.sf.ehcache.config.Configuration;
|
||||
import net.sf.ehcache.config.ConfigurationFactory;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class EhConfigurationReaderTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testDefaultConfiguration()
|
||||
{
|
||||
EhConfigurationTestReader reader =
|
||||
new EhConfigurationTestReader("cache.001.xml");
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
checkDefaultConfiguration(c);
|
||||
checkCacheConfiguration(c, "sonia.test.cache.001", 1000l, 30l, 60l);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testGlobalAttributes()
|
||||
{
|
||||
EhConfigurationTestReader reader =
|
||||
new EhConfigurationTestReader("cache.006.xml");
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
assertFalse(c.getUpdateCheck());
|
||||
assertEquals("512M", c.getMaxBytesLocalDiskAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testMergeAndOverride()
|
||||
{
|
||||
//J-
|
||||
EhConfigurationTestReader reader = new EhConfigurationTestReader(
|
||||
"cache.001.xml",
|
||||
Iterators.forArray("cache.002.xml", "cache.003.xml"),
|
||||
"cache.004.xml"
|
||||
);
|
||||
//J+
|
||||
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
// cache sonia.test.cache.001 override by cache.004.xml
|
||||
checkCacheConfiguration(c, "sonia.test.cache.001", 6l, 2l, 8l);
|
||||
checkCacheConfiguration(c, "sonia.test.cache.002", 2000l, 60l, 120l);
|
||||
checkCacheConfiguration(c, "sonia.test.cache.003", 3000l, 120l, 2400l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testMergeWithManualConfiguration()
|
||||
{
|
||||
EhConfigurationTestReader reader =
|
||||
new EhConfigurationTestReader("cache.001.xml", null, "cache.002.xml");
|
||||
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
checkDefaultConfiguration(c);
|
||||
|
||||
checkCacheConfiguration(c, "sonia.test.cache.001", 1000l, 30l, 60l);
|
||||
checkCacheConfiguration(c, "sonia.test.cache.002", 2000l, 60l, 120l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testMergeWithModuleConfigurations()
|
||||
{
|
||||
EhConfigurationTestReader reader =
|
||||
new EhConfigurationTestReader("cache.001.xml",
|
||||
Iterators.forArray("cache.002.xml", "cache.003.xml"));
|
||||
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
checkDefaultConfiguration(c);
|
||||
|
||||
checkCacheConfiguration(c, "sonia.test.cache.001", 1000l, 30l, 60l);
|
||||
checkCacheConfiguration(c, "sonia.test.cache.002", 2000l, 60l, 120l);
|
||||
checkCacheConfiguration(c, "sonia.test.cache.003", 3000l, 120l, 2400l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testMissingDefaultConfiguration()
|
||||
{
|
||||
EhConfigurationTestReader reader = new EhConfigurationTestReader();
|
||||
|
||||
reader.read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testOverrideDefaultConfiguration()
|
||||
{
|
||||
//J-
|
||||
EhConfigurationTestReader reader = new EhConfigurationTestReader(
|
||||
"cache.001.xml",
|
||||
Iterators.forArray("cache.005.xml")
|
||||
);
|
||||
//J+
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
checkDefaultConfiguration(c, 170l, 18900l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testOverrideGlobalAttributes()
|
||||
{
|
||||
EhConfigurationTestReader reader =
|
||||
new EhConfigurationTestReader("cache.006.xml", null, "cache.007.xml");
|
||||
Configuration c = createConfiguration(reader);
|
||||
|
||||
assertTrue(c.getUpdateCheck());
|
||||
assertEquals("1G", c.getMaxBytesLocalDiskAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param c
|
||||
* @param name
|
||||
* @param maxEntriesLocalHeap
|
||||
* @param timeToIdleSeconds
|
||||
* @param timeToLiveSeconds
|
||||
*/
|
||||
private void checkCacheConfiguration(Configuration c, String name,
|
||||
long maxEntriesLocalHeap, long timeToIdleSeconds, long timeToLiveSeconds)
|
||||
{
|
||||
CacheConfiguration cc = c.getCacheConfigurations().get(name);
|
||||
|
||||
assertNotNull(cc);
|
||||
assertEquals(maxEntriesLocalHeap, cc.getMaxEntriesLocalHeap());
|
||||
assertEquals(timeToIdleSeconds, cc.getTimeToIdleSeconds());
|
||||
assertEquals(timeToLiveSeconds, cc.getTimeToLiveSeconds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param c
|
||||
*/
|
||||
private void checkDefaultConfiguration(Configuration c)
|
||||
{
|
||||
checkDefaultConfiguration(c, 100l, 10000l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param c
|
||||
* @param maxEntriesLocalHeap
|
||||
* @param maxEntriesLocalDisk
|
||||
*/
|
||||
private void checkDefaultConfiguration(Configuration c,
|
||||
long maxEntriesLocalHeap, long maxEntriesLocalDisk)
|
||||
{
|
||||
CacheConfiguration dcc = c.getDefaultCacheConfiguration();
|
||||
|
||||
assertNotNull(dcc);
|
||||
assertEquals(maxEntriesLocalHeap, dcc.getMaxEntriesLocalHeap());
|
||||
assertEquals(maxEntriesLocalDisk, dcc.getMaxEntriesLocalDisk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param reader
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Configuration createConfiguration(EhCacheConfigurationReader reader)
|
||||
{
|
||||
Configuration config = null;
|
||||
InputStream content = null;
|
||||
|
||||
try
|
||||
{
|
||||
content = reader.read();
|
||||
config = ConfigurationFactory.parseConfiguration(content);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Closeables.closeQuietly(content);
|
||||
}
|
||||
|
||||
assertNotNull(config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 13/03/19
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private class EhConfigurationTestReader extends EhCacheConfigurationReader
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public EhConfigurationTestReader() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param defaultConfiguration
|
||||
*/
|
||||
public EhConfigurationTestReader(String defaultConfiguration)
|
||||
{
|
||||
this.defaultConfiguration = defaultConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param defaultConfiguration
|
||||
* @param moduleConfigurations
|
||||
*/
|
||||
public EhConfigurationTestReader(String defaultConfiguration,
|
||||
Iterator<String> moduleConfigurations)
|
||||
{
|
||||
this.defaultConfiguration = defaultConfiguration;
|
||||
this.moduleConfigurations = moduleConfigurations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param defaultConfiguration
|
||||
* @param moduleConfigurations
|
||||
* @param manualConfiguration
|
||||
*/
|
||||
public EhConfigurationTestReader(String defaultConfiguration,
|
||||
Iterator<String> moduleConfigurations, String manualConfiguration)
|
||||
{
|
||||
this.defaultConfiguration = defaultConfiguration;
|
||||
this.moduleConfigurations = moduleConfigurations;
|
||||
this.manualConfiguration = manualConfiguration;
|
||||
}
|
||||
|
||||
//~--- get methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public URL getDefaultResource()
|
||||
{
|
||||
URL url = null;
|
||||
|
||||
if (defaultConfiguration != null)
|
||||
{
|
||||
url = getResource(defaultConfiguration);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Iterator<URL> getModuleResources()
|
||||
{
|
||||
Iterator<URL> urlIterator;
|
||||
|
||||
if (moduleConfigurations == null)
|
||||
{
|
||||
urlIterator = Iterators.emptyIterator();
|
||||
}
|
||||
else
|
||||
{
|
||||
urlIterator = Iterators.transform(moduleConfigurations,
|
||||
new Function<String, URL>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public URL apply(String resource)
|
||||
{
|
||||
return getResource(resource);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return urlIterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected File getManualFileResource()
|
||||
{
|
||||
File file;
|
||||
|
||||
if (manualConfiguration == null)
|
||||
{
|
||||
file = mock(File.class);
|
||||
when(file.exists()).thenReturn(Boolean.FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
file = tempFolder.newFile();
|
||||
|
||||
URL manual = getResource(manualConfiguration);
|
||||
|
||||
Files.copy(Resources.newInputStreamSupplier(manual), file);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException("could not create manual config file", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private URL getResource(String name)
|
||||
{
|
||||
return Resources.getResource("sonia/scm/cache/".concat(name));
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String defaultConfiguration;
|
||||
|
||||
/** Field description */
|
||||
private String manualConfiguration;
|
||||
|
||||
/** Field description */
|
||||
private Iterator<String> moduleConfigurations;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@Rule
|
||||
public TemporaryFolder tempFolder = new TemporaryFolder();
|
||||
}
|
||||
52
scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheManagerTest.java
vendored
Normal file
52
scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheManagerTest.java
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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 GuavaCacheManagerTest extends CacheManagerTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected CacheManager createCacheManager()
|
||||
{
|
||||
return CacheTestUtil.createDefaultGuavaCacheManager();
|
||||
}
|
||||
}
|
||||
54
scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheTest.java
vendored
Normal file
54
scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheTest.java
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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 ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class GuavaCacheTest extends CacheTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected CacheManager createCacheManager()
|
||||
{
|
||||
return CacheTestUtil.createDefaultGuavaCacheManager();
|
||||
}
|
||||
}
|
||||
50
scm-webapp/src/test/resources/sonia/scm/cache/cache.001.xml
vendored
Normal file
50
scm-webapp/src/test/resources/sonia/scm/cache/cache.001.xml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
|
||||
|
||||
<diskStore path="java.io.tmpdir"/>
|
||||
|
||||
<defaultCache
|
||||
maxEntriesLocalHeap="100"
|
||||
maxEntriesLocalDisk="10000"
|
||||
/>
|
||||
|
||||
<cache
|
||||
name="sonia.test.cache.001"
|
||||
maxEntriesLocalHeap="1000"
|
||||
timeToIdleSeconds="30"
|
||||
timeToLiveSeconds="60"
|
||||
/>
|
||||
|
||||
</ehcache>
|
||||
44
scm-webapp/src/test/resources/sonia/scm/cache/cache.002.xml
vendored
Normal file
44
scm-webapp/src/test/resources/sonia/scm/cache/cache.002.xml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
|
||||
|
||||
|
||||
<cache
|
||||
name="sonia.test.cache.002"
|
||||
maxEntriesLocalHeap="2000"
|
||||
timeToIdleSeconds="60"
|
||||
timeToLiveSeconds="120"
|
||||
/>
|
||||
|
||||
</ehcache>
|
||||
44
scm-webapp/src/test/resources/sonia/scm/cache/cache.003.xml
vendored
Normal file
44
scm-webapp/src/test/resources/sonia/scm/cache/cache.003.xml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
|
||||
|
||||
|
||||
<cache
|
||||
name="sonia.test.cache.003"
|
||||
maxEntriesLocalHeap="3000"
|
||||
timeToIdleSeconds="120"
|
||||
timeToLiveSeconds="2400"
|
||||
/>
|
||||
|
||||
</ehcache>
|
||||
44
scm-webapp/src/test/resources/sonia/scm/cache/cache.004.xml
vendored
Normal file
44
scm-webapp/src/test/resources/sonia/scm/cache/cache.004.xml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
|
||||
|
||||
|
||||
<cache
|
||||
name="sonia.test.cache.001"
|
||||
maxEntriesLocalHeap="6"
|
||||
timeToIdleSeconds="2"
|
||||
timeToLiveSeconds="8"
|
||||
/>
|
||||
|
||||
</ehcache>
|
||||
41
scm-webapp/src/test/resources/sonia/scm/cache/cache.005.xml
vendored
Normal file
41
scm-webapp/src/test/resources/sonia/scm/cache/cache.005.xml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
|
||||
|
||||
<defaultCache
|
||||
maxEntriesLocalHeap="170"
|
||||
maxEntriesLocalDisk="18900"
|
||||
/>
|
||||
|
||||
</ehcache>
|
||||
38
scm-webapp/src/test/resources/sonia/scm/cache/cache.006.xml
vendored
Normal file
38
scm-webapp/src/test/resources/sonia/scm/cache/cache.006.xml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd"
|
||||
updateCheck="false"
|
||||
maxBytesLocalDisk="512M">
|
||||
|
||||
</ehcache>
|
||||
38
scm-webapp/src/test/resources/sonia/scm/cache/cache.007.xml
vendored
Normal file
38
scm-webapp/src/test/resources/sonia/scm/cache/cache.007.xml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--*
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<ehcache xmlns="http://ehcache.org/ehcache.xsd"
|
||||
updateCheck="true"
|
||||
maxBytesLocalDisk="1G">
|
||||
|
||||
</ehcache>
|
||||
86
support/scm-script-plugin/analyze-ehcache.groovy
Normal file
86
support/scm-script-plugin/analyze-ehcache.groovy
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
// see https://bitbucket.org/sdorra/scm-manager/issue/345/ehcache-eating-up-all-memory
|
||||
|
||||
def humanReadable(def bytes) {
|
||||
if (bytes < 1024) return bytes + " B";
|
||||
int exp = (int) (Math.log(bytes) / Math.log(1024));
|
||||
String pre = "KMGTPE".charAt(exp-1);
|
||||
return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
|
||||
}
|
||||
|
||||
def sizeOf(Serializable object){
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(object);
|
||||
oos.close();
|
||||
return baos.size();
|
||||
}
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
def maxMemory = runtime.maxMemory();
|
||||
def allocatedMemory = runtime.totalMemory();
|
||||
def freeMemory = runtime.freeMemory();
|
||||
|
||||
println "memory:"
|
||||
println " - max : " + humanReadable(maxMemory);
|
||||
println " - allocated : " + humanReadable(allocatedMemory);
|
||||
println " - free : " + humanReadable(freeMemory);
|
||||
|
||||
println "";
|
||||
println "";
|
||||
|
||||
def cacheManager = injector.getInstance(sonia.scm.cache.CacheManager.class).cacheManager;
|
||||
|
||||
def totalCMax = 0;
|
||||
|
||||
def cacheNames = cacheManager.getCacheNames();
|
||||
for ( def cacheName : cacheNames ){
|
||||
def cache = cacheManager.getCache(cacheName);
|
||||
def totalMemory = cache.calculateInMemorySize();
|
||||
def average = cache.getSize() > 0 ? Math.round( totalMemory / cache.getSize() ) : 0;
|
||||
def max = cache.getCacheConfiguration().getMaxEntriesLocalHeap();
|
||||
def maxSize = average * max;
|
||||
|
||||
totalCMax += maxSize;
|
||||
|
||||
println cache.name + ":";
|
||||
println " - size : " + cache.getSize();
|
||||
println " - maxsize : " + max;
|
||||
println " - average : " + humanReadable( average );
|
||||
println " - current : " + humanReadable( totalMemory );
|
||||
println " - cmax : " + humanReadable( maxSize );
|
||||
}
|
||||
|
||||
println "";
|
||||
println "";
|
||||
println "Total CMax: " + humanReadable(totalCMax);
|
||||
Reference in New Issue
Block a user