org.wamblee.persistence.PersistentFactory Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2005-2010 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
*
* http://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 org.wamblee.persistence;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.Id;
import javax.persistence.Version;
import org.wamblee.reflection.Accessor;
import org.wamblee.reflection.AnnotationUtils;
/**
* Factory which creates a {@link Persistent} object for a given JPA entity for
* interfacing with the primary key and version of the entity.
*
* This utility only treats primary keys and fields that are annotated with @Id
* and @Version. In case ORM files are used for the definition of primary key
* and or version, then those fields are ignored.
*
* @author Erik Brakkee
*
*/
public class PersistentFactory {
/**
* Cache of a mapping of class names to entity accessors.
*/
private static Map CACHE = new ConcurrentHashMap();
static class EntityAccessor {
private Accessor pk;
private Accessor version;
public EntityAccessor(Accessor> aPk, Accessor> aVersion) {
pk = aPk;
version = aVersion;
}
public Accessor getPk() {
return pk;
}
public Accessor getVersion() {
return version;
}
}
public static class EntityObjectAccessor implements Persistent {
private EntityAccessor accessor;
private Object entity;
public EntityObjectAccessor(Object aEntity, EntityAccessor aAccessor) {
accessor = aAccessor;
entity = aEntity;
}
public EntityAccessor getAccessor() {
return accessor;
};
@Override
public Serializable getPrimaryKey() {
if (accessor == null || accessor.getPk() == null) {
return null;
}
return (Serializable) accessor.getPk().get(entity);
}
@Override
public void setPrimaryKey(Serializable aKey) {
if (accessor == null || accessor.getPk() == null) {
return;
}
accessor.getPk().set(entity, aKey);
}
@Override
public Number getPersistedVersion() {
if (accessor == null || accessor.getVersion() == null) {
return null;
}
return (Number) accessor.getVersion().get(entity);
}
@Override
public void setPersistedVersion(Number aVersion) {
if (accessor == null || accessor.getVersion() == null) {
return;
}
accessor.getVersion().set(entity, aVersion);
}
}
/**
* Create the entity accessor for a given class or returns a cached instance
* if one already exists.
*
* @param aClass
* Class.
* @return Entity accessor for the given class or null of the given object
* is not an entity.
*/
public static EntityAccessor createEntityAccessor(Class aClass) {
EntityAccessor accessor = CACHE.get(aClass.getName());
if (accessor == null) {
accessor = analyse(aClass);
if (accessor != null) {
CACHE.put(aClass.getName(), accessor);
}
}
return accessor;
}
private static EntityAccessor analyse(Class aClass) {
List pkAccessors = AnnotationUtils.analyse(aClass, Id.class);
List versionAccessors = AnnotationUtils.analyse(aClass,
Version.class);
Accessor pk = null;
if (pkAccessors.size() > 0) {
pk = pkAccessors.get(0);
}
Accessor version = null;
if (versionAccessors.size() > 0) {
version = versionAccessors.get(0);
}
if (pk != null || version != null) {
return new EntityAccessor(pk, version);
}
return null;
}
/**
* Creates the {@link Persistent} wrapper for interfacing with primary key
* and version of the entity.
*
* @param aEntity
* Entity to use.
* @return Persistent object or null if this is not an entity.
*/
public static Persistent create(Object aEntity) {
EntityAccessor accessor = createEntityAccessor(aEntity.getClass());
if (accessor == null) {
return null;
}
return new EntityObjectAccessor(aEntity, accessor);
}
}