qnameCache;
/**
* Default constructor.
*
* This sets up the DAO accessors to bypass any caching to handle the case where the caches are not
* supplied in the setters.
*/
protected AbstractQNameDAOImpl()
{
this.namespaceCache = new EntityLookupCache(new NamespaceCallbackDAO());
this.qnameCache = new EntityLookupCache(new QNameCallbackDAO());
}
/**
* Set the cache that maintains the ID-Namespace mappings and vice-versa.
*
* @param namespaceCache the cache
*/
public void setNamespaceCache(SimpleCache namespaceCache)
{
this.namespaceCache = new EntityLookupCache(
namespaceCache,
CACHE_REGION_NAMESPACE,
new NamespaceCallbackDAO());
}
/**
* Set the cache that maintains the ID-Namespace mappings and vice-versa.
*
* @param qnameCache the cache
*/
public void setQnameCache(SimpleCache qnameCache)
{
this.qnameCache = new EntityLookupCache(
qnameCache,
CACHE_REGION_QNAME,
new QNameCallbackDAO());
}
//================================
// 'alf_namespace' accessors
//================================
public Pair getNamespace(Long id)
{
if (id == null)
{
throw new IllegalArgumentException("Cannot look up entity by null ID.");
}
Pair entityPair = namespaceCache.getByKey(id);
if (entityPair == null)
{
throw new DataIntegrityViolationException("No namespace exists for ID " + id);
}
return entityPair;
}
public Pair getNamespace(String namespaceUri)
{
if (namespaceUri == null)
{
throw new IllegalArgumentException("Namespace URI cannot be null");
}
Pair entityPair = namespaceCache.getByValue(namespaceUri);
return entityPair;
}
public Pair getOrCreateNamespace(String namespaceUri)
{
if (namespaceUri == null)
{
throw new IllegalArgumentException("Namespace URI cannot be null");
}
Pair entityPair = namespaceCache.getOrCreateByValue(namespaceUri);
return entityPair;
}
public void updateNamespace(String oldNamespaceUri, String newNamespaceUri)
{
ParameterCheck.mandatory("newNamespaceUri", newNamespaceUri);
Pair oldEntityPair = getNamespace(oldNamespaceUri); // incl. null check
if (oldEntityPair == null)
{
throw new DataIntegrityViolationException(
"Cannot update namespace as it doesn't exist: " + oldNamespaceUri);
}
// Find the value
int updated = namespaceCache.updateValue(oldEntityPair.getFirst(), newNamespaceUri);
if (updated != 1)
{
throw new ConcurrencyFailureException(
"Incorrect update count: \n" +
" Namespace: " + oldNamespaceUri + "\n" +
" Rows Updated: " + updated);
}
// All the QNames need to be dumped
qnameCache.clear();
// Done
}
/**
* Callback for alf_namespace DAO.
*/
private class NamespaceCallbackDAO extends EntityLookupCallbackDAOAdaptor
{
@Override
public String getValueKey(String value)
{
return value;
}
public Pair findByKey(Long id)
{
NamespaceEntity entity = findNamespaceEntityById(id);
if (entity == null)
{
return null;
}
else
{
return new Pair(id, entity.getUriSafe());
}
}
@Override
public Pair findByValue(String uri)
{
NamespaceEntity entity = findNamespaceEntityByUri(uri);
if (entity == null)
{
return null;
}
else
{
return new Pair(entity.getId(), uri);
}
}
public Pair createValue(String uri)
{
NamespaceEntity entity = createNamespaceEntity(uri);
return new Pair(entity.getId(), uri);
}
@Override
public int updateValue(Long id, String uri)
{
NamespaceEntity entity = findNamespaceEntityById(id);
if (entity == null)
{
// Client can decide if this is a problem
return 0;
}
return updateNamespaceEntity(entity, uri);
}
}
protected abstract NamespaceEntity findNamespaceEntityById(Long id);
protected abstract NamespaceEntity findNamespaceEntityByUri(String uri);
protected abstract NamespaceEntity createNamespaceEntity(String uri);
protected abstract int updateNamespaceEntity(NamespaceEntity entity, String uri);
//================================
// 'alf_qname' accessors
//================================
public Pair getQName(Long id)
{
if (id == null)
{
throw new IllegalArgumentException("Cannot look up entity by null ID.");
}
Pair entityPair = qnameCache.getByKey(id);
if (entityPair == null)
{
throw new DataIntegrityViolationException("No qname exists for ID " + id);
}
return entityPair;
}
public Pair getQName(final QName qname)
{
if (qname == null)
{
throw new IllegalArgumentException("QName cannot be null");
}
Pair entityPair = qnameCache.getByValue(qname);
return entityPair;
}
public Pair getOrCreateQName(QName qname)
{
if (qname == null)
{
throw new IllegalArgumentException("QName cannot be null");
}
Pair entityPair = qnameCache.getOrCreateByValue(qname);
return entityPair;
}
public Pair updateQName(QName qnameOld, QName qnameNew)
{
if (qnameOld == null|| qnameNew == null)
{
throw new IllegalArgumentException("QName cannot be null");
}
if (qnameOld.equals(qnameNew))
{
throw new IllegalArgumentException("Cannot update QNames: they are the same");
}
// See if the old QName exists
Pair qnameOldPair = qnameCache.getByValue(qnameOld);
if (qnameOldPair == null)
{
throw new IllegalArgumentException("Cannot rename QName. QName " + qnameOld + " does not exist");
}
// See if the new QName exists
if (qnameCache.getByValue(qnameNew) != null)
{
throw new IllegalArgumentException("Cannot rename QName. QName " + qnameNew + " already exists");
}
// Update
Long qnameId = qnameOldPair.getFirst();
int updated = qnameCache.updateValue(qnameId, qnameNew);
if (updated != 1)
{
throw new ConcurrencyFailureException("Failed to update QName entity " + qnameId);
}
return new Pair(qnameId, qnameNew);
}
/**
* Callback for alf_qname DAO.
*/
private class QNameCallbackDAO extends EntityLookupCallbackDAOAdaptor
{
@Override
public QName getValueKey(QName value)
{
return value;
}
public Pair findByKey(Long id)
{
QNameEntity entity = findQNameEntityById(id);
if (entity == null)
{
return null;
}
else
{
Long namespaceId = entity.getNamespaceId();
String uri = getNamespace(namespaceId).getSecond();
String localName = entity.getLocalNameSafe();
QName qname = QName.createQName(uri, localName);
return new Pair(id, qname);
}
}
@Override
public Pair findByValue(QName qname)
{
String uri = qname.getNamespaceURI();
String localName = qname.getLocalName();
Pair namespaceEntity = getNamespace(uri);
if (namespaceEntity == null)
{
// There is no match on NS, so there is no QName like this
return null;
}
Long nsId = namespaceEntity.getFirst();
QNameEntity entity = findQNameEntityByNamespaceAndLocalName(nsId, localName);
if (entity == null)
{
return null;
}
else
{
return new Pair(entity.getId(), qname);
}
}
public Pair createValue(QName qname)
{
String uri = qname.getNamespaceURI();
String localName = qname.getLocalName();
// Create namespace
Pair namespaceEntity = getOrCreateNamespace(uri);
Long nsId = namespaceEntity.getFirst();
// Create QName
QNameEntity entity = createQNameEntity(nsId, localName);
return new Pair(entity.getId(), qname);
}
@Override
public int updateValue(Long id, QName qname)
{
String uri = qname.getNamespaceURI();
String localName = qname.getLocalName();
QNameEntity entity = findQNameEntityById(id);
if (entity == null)
{
// No chance of updating
return 0;
}
// Create namespace
Pair namespaceEntity = getOrCreateNamespace(uri);
Long nsId = namespaceEntity.getFirst();
// Create QName
return updateQNameEntity(entity, nsId, localName);
}
}
protected abstract QNameEntity findQNameEntityById(Long id);
protected abstract QNameEntity findQNameEntityByNamespaceAndLocalName(Long nsId, String localName);
protected abstract QNameEntity createQNameEntity(Long nsId, String localName);
protected abstract int updateQNameEntity(QNameEntity entity, Long nsId, String localName);
//================================
// Utility method implementations
//================================
public Set convertIdsToQNames(Set ids)
{
Set qnames = new HashSet(ids.size() * 2 + 1);
for (Long id : ids)
{
QName qname = getQName(id).getSecond(); // getQName(id) is never null
qnames.add(qname);
}
return qnames;
}
public Map convertIdMapToQNameMap(Map idMap)
{
Map qnameMap = new HashMap(idMap.size() + 3);
for (Map.Entry entry : idMap.entrySet())
{
QName qname = getQName(entry.getKey()).getSecond(); // getQName(id) is never null
qnameMap.put(qname, entry.getValue());
}
return qnameMap;
}
/**
* @return Returns a set of IDs mapping to the QNames provided. If create is false
* then there will not be corresponding entries for the QNames that don't exist.
* So there is no guarantee that the returned set will be ordered the same or even
* contain the same number of elements as the original unless create is true.
*/
public Set convertQNamesToIds(Set qnames, boolean create)
{
Set qnameIds = new HashSet(qnames.size(), 1.0F);
for (QName qname : qnames)
{
Long qnameEntityId = null;
if (create)
{
qnameEntityId = getOrCreateQName(qname).getFirst(); // getOrCreateQName(qname) is never null
}
else
{
Pair qnamePair = getQName(qname);
if (qnamePair == null)
{
// No such qname and we are not creating one
continue;
}
else
{
qnameEntityId = qnamePair.getFirst();
}
}
if (qnameEntityId != null)
{
qnameIds.add(qnameEntityId);
}
}
// Done
return qnameIds;
}
}