mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Support 'alf_prop_string_value'
- Simple ID-string table - Non-unique and case-sensitive, but with re-use of entries as far as possible git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15430 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -10,7 +10,6 @@
|
|||||||
CREATE TABLE alf_prop_class
|
CREATE TABLE alf_prop_class
|
||||||
(
|
(
|
||||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
version BIGINT NOT NULL,
|
|
||||||
java_class_name VARCHAR(255) NOT NULL,
|
java_class_name VARCHAR(255) NOT NULL,
|
||||||
java_class_name_short VARCHAR(32) NOT NULL,
|
java_class_name_short VARCHAR(32) NOT NULL,
|
||||||
java_class_name_crc BIGINT NOT NULL,
|
java_class_name_crc BIGINT NOT NULL,
|
||||||
@@ -19,6 +18,24 @@ CREATE TABLE alf_prop_class
|
|||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE alf_prop_string_value
|
||||||
|
(
|
||||||
|
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
|
string_value text NOT NULL,
|
||||||
|
INDEX idx_prop_str_val (string_value(64)),
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
--CREATE TABLE alf_prop_string_value
|
||||||
|
--(
|
||||||
|
-- id BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
|
-- string_value text NOT NULL,
|
||||||
|
-- prop_class_id BIGINT NOT NULL,
|
||||||
|
-- INDEX idx_prop_str_val (string_value(64)),
|
||||||
|
-- CONSTRAINT fk_prop_str_classid FOREIGN KEY (prop_class_id) REFERENCES alf_prop_class (id),
|
||||||
|
-- PRIMARY KEY (id)
|
||||||
|
--) ENGINE=InnoDB;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Record script finish
|
-- Record script finish
|
||||||
--
|
--
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
<typeAlias alias="PropertyClass" type="org.alfresco.repo.domain.propval.PropertyClassEntity"/>
|
<typeAlias alias="PropertyClass" type="org.alfresco.repo.domain.propval.PropertyClassEntity"/>
|
||||||
|
<typeAlias alias="PropertyStringValue" type="org.alfresco.repo.domain.propval.PropertyStringValueEntity"/>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- Result Maps -->
|
<!-- Result Maps -->
|
||||||
@@ -18,11 +19,14 @@
|
|||||||
|
|
||||||
<resultMap id="result.PropertyClass" class="PropertyClass">
|
<resultMap id="result.PropertyClass" class="PropertyClass">
|
||||||
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<result property="version" column="version" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
|
||||||
<result property="javaClassName" column="java_class_name" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
<result property="javaClassName" column="java_class_name" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
<result property="javaClassNameShort" column="java_class_name_short" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
<result property="javaClassNameShort" column="java_class_name_short" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
<result property="javaClassNameCrc" column="java_class_name_crc" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<result property="javaClassNameCrc" column="java_class_name_crc" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
<resultMap id="result.PropertyStringValue" class="PropertyStringValue">
|
||||||
|
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
|
<result property="stringValue" column="string_value" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- Parameter Maps -->
|
<!-- Parameter Maps -->
|
||||||
@@ -43,8 +47,13 @@
|
|||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
<sql id="insert.PropertyClass.AutoIncrement">
|
<sql id="insert.PropertyClass.AutoIncrement">
|
||||||
insert into alf_prop_class (version, java_class_name, java_class_name_short, java_class_name_crc)
|
insert into alf_prop_class (java_class_name, java_class_name_short, java_class_name_crc)
|
||||||
values (#version#, #javaClassName#, #javaClassNameShort#, #javaClassNameCrc#)
|
values (#javaClassName#, #javaClassNameShort#, #javaClassNameCrc#)
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<sql id="insert.PropertyStringValue.AutoIncrement">
|
||||||
|
insert into alf_prop_string_value (string_value)
|
||||||
|
values (#stringValue#)
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@@ -72,4 +81,24 @@
|
|||||||
java_class_name_short = #javaClassNameShort#
|
java_class_name_short = #javaClassNameShort#
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- Get a property string value by ID -->
|
||||||
|
<select id="select.PropertyStringValueByID" parameterClass="PropertyStringValue" resultMap="result.PropertyStringValue">
|
||||||
|
select
|
||||||
|
*
|
||||||
|
from
|
||||||
|
alf_prop_string_value
|
||||||
|
where
|
||||||
|
id = #id#
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- Get the property string value by string -->
|
||||||
|
<select id="select.PropertyStringValueByString" parameterClass="PropertyStringValue" resultMap="result.PropertyStringValue">
|
||||||
|
select
|
||||||
|
*
|
||||||
|
from
|
||||||
|
alf_prop_string_value
|
||||||
|
where
|
||||||
|
string_value = #stringValue#
|
||||||
|
</select>
|
||||||
|
|
||||||
</sqlMap>
|
</sqlMap>
|
@@ -13,4 +13,11 @@
|
|||||||
</selectKey>
|
</selectKey>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<insert id="insert.PropertyStringValue" parameterClass="PropertyStringValue" >
|
||||||
|
<include refid="insert.PropertyStringValue.AutoIncrement"/>
|
||||||
|
<selectKey resultClass="long" keyProperty="id" type="post">
|
||||||
|
KEY_COLUMN:GENERATED_KEY
|
||||||
|
</selectKey>
|
||||||
|
</insert>
|
||||||
|
|
||||||
</sqlMap>
|
</sqlMap>
|
@@ -28,10 +28,12 @@ import java.io.Serializable;
|
|||||||
|
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cache for two-way lookups of database entities. These are characterized by having a unique
|
* A cache for two-way lookups of database entities. These are characterized by having a unique
|
||||||
* key (perhaps a database ID) and a separate unique key that identifies the object.
|
* key (perhaps a database ID) and a separate unique key that identifies the object. If no cache
|
||||||
|
* is given, then all calls are passed through to the backing DAO.
|
||||||
* <p>
|
* <p>
|
||||||
* The keys must have good <code>equals</code> and </code>hashCode</code> implementations and
|
* The keys must have good <code>equals</code> and </code>hashCode</code> implementations and
|
||||||
* must respect the case-sensitivity of the use-case.
|
* must respect the case-sensitivity of the use-case.
|
||||||
@@ -90,6 +92,17 @@ public class EntityLookupCache<K extends Serializable, V extends Object, VK exte
|
|||||||
private final EntityLookupCallbackDAO<K, V, VK> entityLookup;
|
private final EntityLookupCallbackDAO<K, V, VK> entityLookup;
|
||||||
private final String cacheRegion;
|
private final String cacheRegion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the lookup cache <b>without any cache</b>. All calls are passed directly to the
|
||||||
|
* underlying DAO entity lookup.
|
||||||
|
*
|
||||||
|
* @param entityLookup the instance that is able to find and persist entities
|
||||||
|
*/
|
||||||
|
public EntityLookupCache(EntityLookupCallbackDAO<K, V, VK> entityLookup)
|
||||||
|
{
|
||||||
|
this(null, CACHE_REGION_DEFAULT, entityLookup);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the lookup cache, using the {@link #CACHE_REGION_DEFAULT default cache region}.
|
* Construct the lookup cache, using the {@link #CACHE_REGION_DEFAULT default cache region}.
|
||||||
*
|
*
|
||||||
@@ -108,21 +121,30 @@ public class EntityLookupCache<K extends Serializable, V extends Object, VK exte
|
|||||||
* All keys will be unique to the given cache region, allowing the cache to be shared
|
* All keys will be unique to the given cache region, allowing the cache to be shared
|
||||||
* between instances of this class.
|
* between instances of this class.
|
||||||
*
|
*
|
||||||
* @param cache the cache that will back the two-way lookups
|
* @param cache the cache that will back the two-way lookups; <tt>null</tt> to have no backing
|
||||||
|
* in a cache.
|
||||||
* @param cacheRegion the region within the cache to use.
|
* @param cacheRegion the region within the cache to use.
|
||||||
* @param entityLookup the instance that is able to find and persist entities
|
* @param entityLookup the instance that is able to find and persist entities
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public EntityLookupCache(SimpleCache cache, String cacheRegion, EntityLookupCallbackDAO<K, V, VK> entityLookup)
|
public EntityLookupCache(SimpleCache cache, String cacheRegion, EntityLookupCallbackDAO<K, V, VK> entityLookup)
|
||||||
{
|
{
|
||||||
|
ParameterCheck.mandatory("cacheRegion", cacheRegion);
|
||||||
|
ParameterCheck.mandatory("entityLookup", entityLookup);
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.entityLookup = entityLookup;
|
|
||||||
this.cacheRegion = cacheRegion;
|
this.cacheRegion = cacheRegion;
|
||||||
|
this.entityLookup = entityLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Pair<K, V> getByKey(K key)
|
public Pair<K, V> getByKey(K key)
|
||||||
{
|
{
|
||||||
|
// Handle missing cache
|
||||||
|
if (cache == null)
|
||||||
|
{
|
||||||
|
return entityLookup.findByKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
CacheRegionKey cacheKey = new CacheRegionKey(cacheRegion, key);
|
CacheRegionKey cacheKey = new CacheRegionKey(cacheRegion, key);
|
||||||
// Look in the cache
|
// Look in the cache
|
||||||
V value = (V) cache.get(cacheKey);
|
V value = (V) cache.get(cacheKey);
|
||||||
@@ -154,6 +176,12 @@ public class EntityLookupCache<K extends Serializable, V extends Object, VK exte
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Pair<K, V> getByValue(V value)
|
public Pair<K, V> getByValue(V value)
|
||||||
{
|
{
|
||||||
|
// Handle missing cache
|
||||||
|
if (cache == null)
|
||||||
|
{
|
||||||
|
return entityLookup.findByValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
// Get the value key
|
// Get the value key
|
||||||
VK valueKey = entityLookup.getValueKey(value);
|
VK valueKey = entityLookup.getValueKey(value);
|
||||||
CacheRegionKey cacheKey = new CacheRegionKey(cacheRegion, valueKey);
|
CacheRegionKey cacheKey = new CacheRegionKey(cacheRegion, valueKey);
|
||||||
@@ -189,6 +217,17 @@ public class EntityLookupCache<K extends Serializable, V extends Object, VK exte
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Pair<K, V> getOrCreateByValue(V value)
|
public Pair<K, V> getOrCreateByValue(V value)
|
||||||
{
|
{
|
||||||
|
// Handle missing cache
|
||||||
|
if (cache == null)
|
||||||
|
{
|
||||||
|
Pair<K, V> entityPair = entityLookup.findByValue(value);
|
||||||
|
if (entityPair == null)
|
||||||
|
{
|
||||||
|
entityPair = entityLookup.createValue(value);
|
||||||
|
}
|
||||||
|
return entityPair;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the value key
|
// Get the value key
|
||||||
VK valueKey = entityLookup.getValueKey(value);
|
VK valueKey = entityLookup.getValueKey(value);
|
||||||
CacheRegionKey cacheKey = new CacheRegionKey(cacheRegion, valueKey);
|
CacheRegionKey cacheKey = new CacheRegionKey(cacheRegion, valueKey);
|
||||||
|
@@ -30,6 +30,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
|||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.repo.cache.lookup.EntityLookupCache;
|
import org.alfresco.repo.cache.lookup.EntityLookupCache;
|
||||||
import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAO;
|
import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAO;
|
||||||
|
import org.alfresco.repo.domain.CrcHelper;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,20 +45,69 @@ import org.alfresco.util.Pair;
|
|||||||
public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||||
{
|
{
|
||||||
private static final String CACHE_REGION_PROPERTY_CLASS = "PropertyClass";
|
private static final String CACHE_REGION_PROPERTY_CLASS = "PropertyClass";
|
||||||
|
private static final String CACHE_REGION_PROPERTY_STRING_VALUE = "PropertyStringValue";
|
||||||
|
|
||||||
|
private final PropertyClassCallbackDAO propertyClassDaoCallback;
|
||||||
|
private final PropertyStringValueCallbackDAO propertyStringValueCallback;
|
||||||
|
/**
|
||||||
|
* Cache for the property class:<br/>
|
||||||
|
* KEY: ID<br/>
|
||||||
|
* VALUE: Java class<br/>
|
||||||
|
* VALUE KEY: Java class name<br/>
|
||||||
|
*/
|
||||||
private EntityLookupCache<Long, Class<?>, String> propertyClassCache;
|
private EntityLookupCache<Long, Class<?>, String> propertyClassCache;
|
||||||
|
/**
|
||||||
|
* Cache for the property string value:<br/>
|
||||||
|
* KEY: ID<br/>
|
||||||
|
* VALUE: The full string<br/>
|
||||||
|
* VALUE KEY: Short string-crc pair ({@link CrcHelper#getStringCrcPair(String, int, boolean, boolean)})<br/>
|
||||||
|
*/
|
||||||
|
private EntityLookupCache<Long, String, Pair<String, Long>> propertyStringValueCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
* <p>
|
||||||
|
* This sets up the DAO accessors to bypass any caching to handle the case where the caches are not
|
||||||
|
* supplied in the setters.
|
||||||
|
*/
|
||||||
|
public AbstractPropertyValueDAOImpl()
|
||||||
|
{
|
||||||
|
this.propertyClassDaoCallback = new PropertyClassCallbackDAO();
|
||||||
|
this.propertyStringValueCallback = new PropertyStringValueCallbackDAO();
|
||||||
|
|
||||||
|
this.propertyClassCache = new EntityLookupCache<Long, Class<?>, String>(propertyClassDaoCallback);
|
||||||
|
this.propertyStringValueCache = new EntityLookupCache<Long, String, Pair<String, Long>>(propertyStringValueCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the cache to use for <b>alf_prop_class</b> lookups (optional).
|
||||||
*
|
*
|
||||||
* @param propertyClassCache the cache of IDs to property classes
|
* @param propertyClassCache the cache of IDs to property classes
|
||||||
*/
|
*/
|
||||||
public void setPropertyClassCache(SimpleCache<Serializable, Object> propertyClassCache)
|
public void setPropertyClassCache(SimpleCache<Serializable, Object> propertyClassCache)
|
||||||
{
|
{
|
||||||
PropertyValueCallbackDAO daoCallback = new PropertyValueCallbackDAO();
|
|
||||||
this.propertyClassCache = new EntityLookupCache<Long, Class<?>, String>(
|
this.propertyClassCache = new EntityLookupCache<Long, Class<?>, String>(
|
||||||
propertyClassCache,
|
propertyClassCache,
|
||||||
CACHE_REGION_PROPERTY_CLASS,
|
CACHE_REGION_PROPERTY_CLASS,
|
||||||
daoCallback);
|
propertyClassDaoCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the cache to use for <b>alf_prop_string_value</b> lookups (optional).
|
||||||
|
*
|
||||||
|
* @param propertyStringValueCache the cache of IDs to property string values
|
||||||
|
*/
|
||||||
|
public void setPropertyStringValueCache(SimpleCache<Serializable, Object> propertyStringValueCache)
|
||||||
|
{
|
||||||
|
this.propertyStringValueCache = new EntityLookupCache<Long, String, Pair<String, Long>>(
|
||||||
|
propertyStringValueCache,
|
||||||
|
CACHE_REGION_PROPERTY_STRING_VALUE,
|
||||||
|
propertyStringValueCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================
|
||||||
|
// 'alf_prop_class' accessors
|
||||||
|
//================================
|
||||||
|
|
||||||
public Pair<Long, Class<?>> getPropertyClass(Long id)
|
public Pair<Long, Class<?>> getPropertyClass(Long id)
|
||||||
{
|
{
|
||||||
@@ -69,22 +119,22 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
|||||||
return entityPair;
|
return entityPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Long, Class<?>> getPropertyClass(Class<?> clazz)
|
public Pair<Long, Class<?>> getPropertyClass(Class<?> value)
|
||||||
{
|
{
|
||||||
Pair<Long, Class<?>> entityPair = propertyClassCache.getByValue(clazz);
|
Pair<Long, Class<?>> entityPair = propertyClassCache.getByValue(value);
|
||||||
return entityPair;
|
return entityPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Long, Class<?>> getOrCreatePropertyClass(Class<?> clazz)
|
public Pair<Long, Class<?>> getOrCreatePropertyClass(Class<?> value)
|
||||||
{
|
{
|
||||||
Pair<Long, Class<?>> entityPair = propertyClassCache.getOrCreateByValue(clazz);
|
Pair<Long, Class<?>> entityPair = propertyClassCache.getOrCreateByValue(value);
|
||||||
return entityPair;
|
return entityPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for <b>alf_prop_type</b> DAO.
|
* Callback for <b>alf_prop_class</b> DAO.
|
||||||
*/
|
*/
|
||||||
private class PropertyValueCallbackDAO implements EntityLookupCallbackDAO<Long, Class<?>, String>
|
private class PropertyClassCallbackDAO implements EntityLookupCallbackDAO<Long, Class<?>, String>
|
||||||
{
|
{
|
||||||
private final Pair<Long, Class<?>> convertEntityToPair(PropertyClassEntity propertyClassEntity)
|
private final Pair<Long, Class<?>> convertEntityToPair(PropertyClassEntity propertyClassEntity)
|
||||||
{
|
{
|
||||||
@@ -105,24 +155,96 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
|||||||
|
|
||||||
public Pair<Long, Class<?>> createValue(Class<?> value)
|
public Pair<Long, Class<?>> createValue(Class<?> value)
|
||||||
{
|
{
|
||||||
PropertyClassEntity propertyClassEntity = createClass(value);
|
PropertyClassEntity entity = createClass(value);
|
||||||
return convertEntityToPair(propertyClassEntity);
|
return convertEntityToPair(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Long, Class<?>> findByKey(Long key)
|
public Pair<Long, Class<?>> findByKey(Long key)
|
||||||
{
|
{
|
||||||
PropertyClassEntity propertyClassEntity = findClassById(key);
|
PropertyClassEntity entity = findClassById(key);
|
||||||
return convertEntityToPair(propertyClassEntity);
|
return convertEntityToPair(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Long, Class<?>> findByValue(Class<?> value)
|
public Pair<Long, Class<?>> findByValue(Class<?> value)
|
||||||
{
|
{
|
||||||
PropertyClassEntity propertyClassEntity = findClassByValue(value);
|
PropertyClassEntity entity = findClassByValue(value);
|
||||||
return convertEntityToPair(propertyClassEntity);
|
return convertEntityToPair(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract PropertyClassEntity createClass(Class<?> value);
|
|
||||||
protected abstract PropertyClassEntity findClassById(Long id);
|
protected abstract PropertyClassEntity findClassById(Long id);
|
||||||
protected abstract PropertyClassEntity findClassByValue(Class<?> value);
|
protected abstract PropertyClassEntity findClassByValue(Class<?> value);
|
||||||
|
protected abstract PropertyClassEntity createClass(Class<?> value);
|
||||||
|
|
||||||
|
//================================
|
||||||
|
// 'alf_prop_string_value' accessors
|
||||||
|
//================================
|
||||||
|
|
||||||
|
public Pair<Long, String> getPropertyStringValue(Long id)
|
||||||
|
{
|
||||||
|
Pair<Long, String> entityPair = propertyStringValueCache.getByKey(id);
|
||||||
|
if (entityPair == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("No property class exists for ID " + id);
|
||||||
|
}
|
||||||
|
return entityPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Long, String> getPropertyStringValue(String value)
|
||||||
|
{
|
||||||
|
Pair<Long, String> entityPair = propertyStringValueCache.getByValue(value);
|
||||||
|
return entityPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Long, String> getOrCreatePropertyStringValue(String value)
|
||||||
|
{
|
||||||
|
Pair<Long, String> entityPair = propertyStringValueCache.getOrCreateByValue(value);
|
||||||
|
return entityPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for <b>alf_prop_string_value</b> DAO.
|
||||||
|
*/
|
||||||
|
private class PropertyStringValueCallbackDAO implements EntityLookupCallbackDAO<Long, String, Pair<String, Long>>
|
||||||
|
{
|
||||||
|
private final Pair<Long, String> convertEntityToPair(PropertyStringValueEntity propertyStringValueEntity)
|
||||||
|
{
|
||||||
|
if (propertyStringValueEntity == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return propertyStringValueEntity.getEntityPair();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<String, Long> getValueKey(String value)
|
||||||
|
{
|
||||||
|
return CrcHelper.getStringCrcPair(value, 128, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Long, String> createValue(String value)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity entity = createStringValue(value);
|
||||||
|
return convertEntityToPair(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Long, String> findByKey(Long key)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity entity = findStringValueById(key);
|
||||||
|
return convertEntityToPair(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Long, String> findByValue(String value)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity entity = findStringValueByValue(value);
|
||||||
|
return convertEntityToPair(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract PropertyStringValueEntity findStringValueById(Long id);
|
||||||
|
protected abstract PropertyStringValueEntity findStringValueByValue(String value);
|
||||||
|
protected abstract PropertyStringValueEntity createStringValue(String value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -37,11 +37,7 @@ import org.alfresco.util.Pair;
|
|||||||
*/
|
*/
|
||||||
public class PropertyClassEntity
|
public class PropertyClassEntity
|
||||||
{
|
{
|
||||||
public static final Long CONST_LONG_ZERO = new Long(0L);
|
|
||||||
public static final String EMPTY_URL = "empty";
|
|
||||||
|
|
||||||
private Long id;
|
private Long id;
|
||||||
private Long version;
|
|
||||||
private Class<?> javaClass;
|
private Class<?> javaClass;
|
||||||
private String javaClassName;
|
private String javaClassName;
|
||||||
private String javaClassNameShort;
|
private String javaClassNameShort;
|
||||||
@@ -121,16 +117,6 @@ public class PropertyClassEntity
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getVersion()
|
|
||||||
{
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(Long version)
|
|
||||||
{
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJavaClass(Class<?> javaClass)
|
public void setJavaClass(Class<?> javaClass)
|
||||||
{
|
{
|
||||||
this.javaClass = javaClass;
|
this.javaClass = javaClass;
|
||||||
|
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.domain.propval;
|
||||||
|
|
||||||
|
import org.alfresco.util.EqualsHelper;
|
||||||
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity bean for <b>alf_prop_string_value</b> table.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public class PropertyStringValueEntity
|
||||||
|
{
|
||||||
|
private Long id;
|
||||||
|
private String stringValue;
|
||||||
|
|
||||||
|
public PropertyStringValueEntity()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return (stringValue == null ? 0 : stringValue.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if (this == obj)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (obj != null && obj instanceof PropertyStringValueEntity)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity that = (PropertyStringValueEntity) obj;
|
||||||
|
return EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder(512);
|
||||||
|
sb.append("PropertyStringValueEntity")
|
||||||
|
.append("[ ID=").append(id)
|
||||||
|
.append(", stringValue=").append(stringValue)
|
||||||
|
.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Long, String> getEntityPair()
|
||||||
|
{
|
||||||
|
return new Pair<Long, String>(id, stringValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringValue()
|
||||||
|
{
|
||||||
|
return stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStringValue(String stringValue)
|
||||||
|
{
|
||||||
|
this.stringValue = stringValue;
|
||||||
|
}
|
||||||
|
}
|
@@ -34,9 +34,33 @@ import org.alfresco.util.Pair;
|
|||||||
*/
|
*/
|
||||||
public interface PropertyValueDAO
|
public interface PropertyValueDAO
|
||||||
{
|
{
|
||||||
Pair<Long, Class<?>> getPropertyClass(Class<?> clazz);
|
/**
|
||||||
|
* <b>alf_prop_class</b> accessor
|
||||||
|
*/
|
||||||
Pair<Long, Class<?>> getPropertyClass(Long id);
|
Pair<Long, Class<?>> getPropertyClass(Long id);
|
||||||
|
|
||||||
Pair<Long, Class<?>> getOrCreatePropertyClass(Class<?> clazz);
|
/**
|
||||||
|
* <b>alf_prop_class</b> accessor
|
||||||
|
*/
|
||||||
|
Pair<Long, Class<?>> getPropertyClass(Class<?> value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>alf_prop_class</b> accessor
|
||||||
|
*/
|
||||||
|
Pair<Long, Class<?>> getOrCreatePropertyClass(Class<?> value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>alf_prop_string_value</b> accessor
|
||||||
|
*/
|
||||||
|
Pair<Long, String> getPropertyStringValue(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>alf_prop_string_value</b> accessor
|
||||||
|
*/
|
||||||
|
Pair<Long, String> getPropertyStringValue(String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>alf_prop_string_value</b> accessor
|
||||||
|
*/
|
||||||
|
Pair<Long, String> getOrCreatePropertyStringValue(String value);
|
||||||
}
|
}
|
||||||
|
@@ -118,4 +118,54 @@ public class PropertyValueDAOTest extends TestCase
|
|||||||
};
|
};
|
||||||
txnHelper.doInTransaction(noHitCallback, false);
|
txnHelper.doInTransaction(noHitCallback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPropertyStringValue() throws Exception
|
||||||
|
{
|
||||||
|
final String stringValue = "One Two Three";
|
||||||
|
final String stringValueUpper = stringValue.toUpperCase();
|
||||||
|
final String stringValueLower = stringValue.toLowerCase();
|
||||||
|
RetryingTransactionCallback<Pair<Long, String>> createStringCallback = new RetryingTransactionCallback<Pair<Long, String>>()
|
||||||
|
{
|
||||||
|
public Pair<Long, String> execute() throws Throwable
|
||||||
|
{
|
||||||
|
// Get the classes
|
||||||
|
return propertyValueDAO.getOrCreatePropertyStringValue(stringValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final Pair<Long, String> stringEntityPair = txnHelper.doInTransaction(createStringCallback, false);
|
||||||
|
assertNotNull(stringEntityPair);
|
||||||
|
assertNotNull(stringEntityPair.getFirst());
|
||||||
|
assertEquals(stringValue, stringEntityPair.getSecond());
|
||||||
|
|
||||||
|
// Check that the uppercase and lowercase strings don't have entries
|
||||||
|
RetryingTransactionCallback<Void> getClassCallback = new RetryingTransactionCallback<Void>()
|
||||||
|
{
|
||||||
|
public Void execute() throws Throwable
|
||||||
|
{
|
||||||
|
Pair<Long, String> checkPair1 = propertyValueDAO.getPropertyStringValue(stringValue);
|
||||||
|
assertNotNull(checkPair1);
|
||||||
|
assertEquals(stringValue, checkPair1.getSecond());
|
||||||
|
Pair<Long, String> checkPair2 = propertyValueDAO.getPropertyStringValue(stringValueUpper);
|
||||||
|
assertNull(checkPair2);
|
||||||
|
Pair<Long, String> checkPair3 = propertyValueDAO.getPropertyStringValue(stringValueLower);
|
||||||
|
assertNull(checkPair3);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
txnHelper.doInTransaction(getClassCallback, true);
|
||||||
|
|
||||||
|
RetryingTransactionCallback<Pair<Long, String>> createStringUpperCallback = new RetryingTransactionCallback<Pair<Long, String>>()
|
||||||
|
{
|
||||||
|
public Pair<Long, String> execute() throws Throwable
|
||||||
|
{
|
||||||
|
// Get the classes
|
||||||
|
return propertyValueDAO.getOrCreatePropertyStringValue(stringValueUpper);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final Pair<Long, String> stringUpperEntityPair = txnHelper.doInTransaction(createStringUpperCallback, false);
|
||||||
|
assertNotNull(stringUpperEntityPair);
|
||||||
|
assertNotNull(stringUpperEntityPair.getFirst());
|
||||||
|
assertEquals(stringValueUpper, stringUpperEntityPair.getSecond());
|
||||||
|
assertNotSame("String IDs were not different", stringEntityPair.getFirst(), stringUpperEntityPair.getFirst());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,8 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.domain.propval.ibatis;
|
package org.alfresco.repo.domain.propval.ibatis;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.propval.AbstractPropertyValueDAOImpl;
|
import org.alfresco.repo.domain.propval.AbstractPropertyValueDAOImpl;
|
||||||
import org.alfresco.repo.domain.propval.PropertyClassEntity;
|
import org.alfresco.repo.domain.propval.PropertyClassEntity;
|
||||||
|
import org.alfresco.repo.domain.propval.PropertyStringValueEntity;
|
||||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,6 +43,9 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
|
|||||||
private static final String SELECT_PROPERTY_CLASS_BY_ID = "select.PropertyClassByID";
|
private static final String SELECT_PROPERTY_CLASS_BY_ID = "select.PropertyClassByID";
|
||||||
private static final String SELECT_PROPERTY_CLASS_BY_NAME = "select.PropertyClassByName";
|
private static final String SELECT_PROPERTY_CLASS_BY_NAME = "select.PropertyClassByName";
|
||||||
private static final String INSERT_PROPERTY_CLASS = "insert.PropertyClass";
|
private static final String INSERT_PROPERTY_CLASS = "insert.PropertyClass";
|
||||||
|
private static final String SELECT_PROPERTY_STRING_VALUE_BY_ID = "select.PropertyStringValueByID";
|
||||||
|
private static final String SELECT_PROPERTY_STRING_VALUE_BY_STRING = "select.PropertyStringValueByString";
|
||||||
|
private static final String INSERT_PROPERTY_STRING_VALUE = "insert.PropertyStringValue";
|
||||||
|
|
||||||
private SqlMapClientTemplate template;
|
private SqlMapClientTemplate template;
|
||||||
|
|
||||||
@@ -51,32 +57,72 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
|
|||||||
@Override
|
@Override
|
||||||
protected PropertyClassEntity findClassById(Long id)
|
protected PropertyClassEntity findClassById(Long id)
|
||||||
{
|
{
|
||||||
PropertyClassEntity propertyClassEntity = new PropertyClassEntity();
|
PropertyClassEntity entity = new PropertyClassEntity();
|
||||||
propertyClassEntity.setId(id);
|
entity.setId(id);
|
||||||
propertyClassEntity = (PropertyClassEntity) template.queryForObject(SELECT_PROPERTY_CLASS_BY_ID, propertyClassEntity);
|
entity = (PropertyClassEntity) template.queryForObject(SELECT_PROPERTY_CLASS_BY_ID, entity);
|
||||||
// Done
|
// Done
|
||||||
return propertyClassEntity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PropertyClassEntity findClassByValue(Class<?> value)
|
protected PropertyClassEntity findClassByValue(Class<?> value)
|
||||||
{
|
{
|
||||||
PropertyClassEntity propertyClassEntity = new PropertyClassEntity();
|
PropertyClassEntity entity = new PropertyClassEntity();
|
||||||
propertyClassEntity.setJavaClass(value);
|
entity.setJavaClass(value);
|
||||||
propertyClassEntity = (PropertyClassEntity) template.queryForObject(SELECT_PROPERTY_CLASS_BY_NAME, propertyClassEntity);
|
entity = (PropertyClassEntity) template.queryForObject(SELECT_PROPERTY_CLASS_BY_NAME, entity);
|
||||||
// Done
|
// Done
|
||||||
return propertyClassEntity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PropertyClassEntity createClass(Class<?> value)
|
protected PropertyClassEntity createClass(Class<?> value)
|
||||||
{
|
{
|
||||||
PropertyClassEntity propertyClassEntity = new PropertyClassEntity();
|
PropertyClassEntity entity = new PropertyClassEntity();
|
||||||
propertyClassEntity.setJavaClass(value);
|
entity.setJavaClass(value);
|
||||||
propertyClassEntity.setVersion(VERSION_ONE);
|
Long id = (Long) template.insert(INSERT_PROPERTY_CLASS, entity);
|
||||||
Long id = (Long) template.insert(INSERT_PROPERTY_CLASS, propertyClassEntity);
|
entity.setId(id);
|
||||||
propertyClassEntity.setId(id);
|
|
||||||
// Done
|
// Done
|
||||||
return propertyClassEntity;
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PropertyStringValueEntity findStringValueById(Long id)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity entity = new PropertyStringValueEntity();
|
||||||
|
entity.setId(id);
|
||||||
|
entity = (PropertyStringValueEntity) template.queryForObject(SELECT_PROPERTY_STRING_VALUE_BY_ID, entity);
|
||||||
|
// Done
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
protected PropertyStringValueEntity findStringValueByValue(String value)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity entity = new PropertyStringValueEntity();
|
||||||
|
entity.setStringValue(value);
|
||||||
|
List<PropertyStringValueEntity> results = (List<PropertyStringValueEntity>) template.queryForList(SELECT_PROPERTY_STRING_VALUE_BY_STRING, entity);
|
||||||
|
// There are several matches, so find the first one that matches exactly
|
||||||
|
for (PropertyStringValueEntity resultEntity : results)
|
||||||
|
{
|
||||||
|
if (value.equals(resultEntity.getStringValue()))
|
||||||
|
{
|
||||||
|
// Found a match
|
||||||
|
return resultEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No real match
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PropertyStringValueEntity createStringValue(String value)
|
||||||
|
{
|
||||||
|
PropertyStringValueEntity entity = new PropertyStringValueEntity();
|
||||||
|
entity.setStringValue(value);
|
||||||
|
Long id = (Long) template.insert(INSERT_PROPERTY_STRING_VALUE, entity);
|
||||||
|
entity.setId(id);
|
||||||
|
// Done
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user