Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2004-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibatis.sqlmap.engine.cache;
import com.ibatis.common.logging.Log;
import com.ibatis.common.logging.LogFactory;
import com.ibatis.sqlmap.engine.mapping.statement.ExecuteListener;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import java.io.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
/**
* Wrapper for Caches.
*/
public class CacheModel implements ExecuteListener {
/** The Constant log. */
private static final Log log = LogFactory.getLog(CacheModel.class);
/** The Constant MAX_OBJECT_LOG_SIZE. */
private static final int MAX_OBJECT_LOG_SIZE = 200;
/**
* This is used to represent null objects that are returned from the cache so that they can be cached, too.
*/
public static final Object NULL_OBJECT = "SERIALIZABLE_NULL_OBJECT";
/** The requests. */
private int requests = 0;
/** The hits. */
private int hits = 0;
/** Constant to turn off periodic cache flushes. */
private static final long NO_FLUSH_INTERVAL = -99999;
/** The id. */
private String id;
/** The read only. */
private boolean readOnly;
/** The serialize. */
private boolean serialize;
/** The last flush. */
private long lastFlush;
/** The flush interval. */
private long flushInterval;
/** The flush interval seconds. */
private long flushIntervalSeconds;
/** The flush trigger statements. */
private Set flushTriggerStatements;
/** The controller. */
private CacheController controller;
/** The resource. */
private String resource;
/**
* Default constructor.
*/
public CacheModel() {
this.flushInterval = NO_FLUSH_INTERVAL;
this.flushIntervalSeconds = NO_FLUSH_INTERVAL;
this.lastFlush = System.currentTimeMillis();
this.flushTriggerStatements = new HashSet();
}
/**
* Getter for the cache model's id.
*
* @return the id
*/
public String getId() {
return id;
}
/**
* Setter for the cache model's id.
*
* @param id
* - the new id
*/
public void setId(String id) {
this.id = id;
}
/**
* Getter for read-only property.
*
* @return true if a read-only model
*/
public boolean isReadOnly() {
return readOnly;
}
/**
* Setter for read-only property.
*
* @param readOnly
* - the new setting
*/
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
/**
* Getter to tell if the cache serializes.
*
* @return true if the cache model serializes objects
*/
public boolean isSerialize() {
return serialize;
}
/**
* Setter to tell the cache to serialize objects.
*
* @param serialize
* - if the cache model is to serialize objects
*/
public void setSerialize(boolean serialize) {
this.serialize = serialize;
}
/**
* Getter for resource property.
*
* @return the value of the resource property
*/
public String getResource() {
return resource;
}
/**
* Setter for resource property.
*
* @param resource
* - the new value
*/
public void setResource(String resource) {
this.resource = resource;
}
/**
* Sets up the controller for the cache model.
*
* @param controller
* the new cache controller
*
* @throws ClassNotFoundException
* - if the class cannot be found
* @throws InstantiationException
* - if the class cannot be instantiated
* @throws IllegalAccessException
* - if the classes constructor is not accessible
*/
public void setCacheController(CacheController controller)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
this.controller = controller;
}
/**
* Getter for flushInterval property.
*
* @return The flushInterval (in milliseconds)
*/
public long getFlushInterval() {
return flushInterval;
}
/**
* Getter for flushInterval property.
*
* @return The flushInterval (in milliseconds)
*/
public long getFlushIntervalSeconds() {
return flushIntervalSeconds;
}
/**
* Setter for flushInterval property.
*
* @param flushInterval
* The new flushInterval (in milliseconds)
*/
public void setFlushInterval(long flushInterval) {
this.flushInterval = flushInterval;
this.flushIntervalSeconds = flushInterval / 1000;
}
/**
* Adds a flushTriggerStatment. When a flushTriggerStatment is executed, the cache is flushed (cleared).
*
* @param statementName
* The statement to add.
*/
public void addFlushTriggerStatement(String statementName) {
flushTriggerStatements.add(statementName);
}
/**
* Gets an Iterator containing all flushTriggerStatment objects for this cache.
*
* @return The Iterator
*/
public Iterator getFlushTriggerStatementNames() {
return flushTriggerStatements.iterator();
}
/**
* ExecuteListener event. This will be called by a MappedStatement for which this cache is registered as a
* ExecuteListener. It will be called each time an executeXXXXXX method is called. In the case of the Cache class, it
* is registered in order to flush the cache whenever a certain statement is executed. (i.e. the flushOnExecute cache
* policy)
*
* @param statement
* The statement to execute
*/
public void onExecuteStatement(MappedStatement statement) {
flush();
}
/**
* Returns statistical information about the cache.
*
* @return the number of cache hits divided by the total requests
*/
public double getHitRatio() {
return (double) hits / (double) requests;
}
/**
* Configures the cache.
*
* @param props
* the props
*/
public void configure(Properties props) {
controller.setProperties(props);
}
/**
* Clears the cache.
*/
public void flush() {
synchronized (this) {
controller.flush(this);
lastFlush = System.currentTimeMillis();
if (log.isDebugEnabled()) {
log("flushed", false, null);
}
}
}
/**
* Get an object out of the cache. A side effect of this method is that is may clear the cache if it has not been
* cleared in the flushInterval.
*
* @param key
* The key of the object to be returned
*
* @return The cached object (or null)
*/
public Object getObject(CacheKey key) {
Object value = null;
synchronized (this) {
if (flushInterval != NO_FLUSH_INTERVAL && System.currentTimeMillis() - lastFlush > flushInterval) {
flush();
}
value = controller.getObject(this, key);
if (serialize && !readOnly && (value != NULL_OBJECT && value != null)) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream((byte[]) value);
ObjectInputStream ois = new ObjectInputStream(bis);
value = ois.readObject();
ois.close();
} catch (Exception e) {
throw new RuntimeException("Error caching serializable object. Be sure you're not attempting to use "
+ "a serialized cache for an object that may be taking advantage of lazy loading. Cause: " + e, e);
}
}
requests++;
if (value != null) {
hits++;
}
if (log.isDebugEnabled()) {
if (value != null) {
log("retrieved object", true, value);
} else {
log("cache miss", false, null);
}
}
}
return value;
}
/**
* Add an object to the cache.
*
* @param key
* The key of the object to be cached
* @param value
* The object to be cached
*/
public void putObject(CacheKey key, Object value) {
if (null == value)
value = NULL_OBJECT;
synchronized (this) {
if (serialize && !readOnly && value != NULL_OBJECT) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(value);
oos.flush();
oos.close();
value = bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Error caching serializable object. Cause: " + e, e);
}
}
controller.putObject(this, key, value);
if (log.isDebugEnabled()) {
log("stored object", true, value);
}
}
}
/**
* Get the maximum size of an object in the log output.
*
* @return Maximum size of a logged object in the output
*/
protected int getMaxObjectLogSize() {
return MAX_OBJECT_LOG_SIZE;
}
/**
* Log a cache action. Since this method is pretty heavy weight, it's best to enclose it with a log.isDebugEnabled()
* when called.
*
* @param action
* String to output
* @param addValue
* Add the value being cached to the log
* @param cacheValue
* The value being logged
*/
protected void log(String action, boolean addValue, Object cacheValue) {
StringBuilder output = new StringBuilder("Cache '");
output.append(getId());
output.append("': ");
output.append(action);
if (addValue) {
String cacheObjectStr = (cacheValue == null ? "null" : cacheValue.toString());
output.append(" '");
if (cacheObjectStr.length() < getMaxObjectLogSize()) {
output.append(cacheObjectStr);
} else {
output.append(cacheObjectStr.substring(1, getMaxObjectLogSize()));
output.append("...");
}
output.append("'");
}
log.debug(output.toString());
}
/**
* Sets the controller properties.
*
* @param cacheProps
* the new controller properties
*/
public void setControllerProperties(Properties cacheProps) {
controller.setProperties(cacheProps);
}
}