/*
* Copyright 2002-2007 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.internna.iwebmvc.dao;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.internna.iwebmvc.model.DomainEntity;
import org.internna.iwebmvc.model.UUID;
import org.internna.iwebmvc.utils.Assert;
import org.internna.iwebmvc.utils.ClassUtils;
import org.internna.iwebmvc.utils.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
/**
* Basic DAO that implements all non operational functionality.
*
* @author Jose Noheda
* @since 1.0
*/
public abstract class AbstractDAO implements DAO {
protected final Log logger = LogFactory.getLog(getClass());
protected final Query setParameters(Query query, Map<String, Object> parameters) {
if (CollectionUtils.isNotEmpty(parameters))
for (Map.Entry<String, Object> parameter : parameters.entrySet())
query.setParameter(parameter.getKey(), parameter.getValue());
return query;
}
protected final Query prepareQuery(Query query, int offset, int max, Map<String, Object> parameters) {
setParameters(query, parameters)
.setFirstResult(offset > 0 ? offset : 0)
.setMaxResults(max > 0 ? max : MAX_RESULTS);
return query;
}
@Transactional
@Override public final void create(DomainEntity entity) {
create(entity, true);
}
@Transactional(readOnly = true)
@Override public final <T extends DomainEntity> T first(Class<T> entityClass) {
List<T> result = find(entityClass, 0, 1);
return CollectionUtils.isEmpty(result) ? null : result.get(0);
}
@Override
@Transactional(readOnly = true)
public <T extends DomainEntity> List<T> find(Class<T> entity, int offset, int max) {
Assert.notNull(entity);
return findByNamedQuery(entity.getSimpleName() + ".findAll", offset, max, null);
}
@Override
@Transactional
public final void remove(Class<? extends DomainEntity> entityClass, String uuid) {
remove(entityClass, new UUID(uuid));
}
@Override
@Transactional
public final void remove(Class<? extends DomainEntity> entityClass, UUID pk) {
Assert.notNull(pk);
Assert.notNull(entityClass);
remove(getReference(entityClass, pk));
}
@Override
@Transactional
public final void remove(Class<? extends DomainEntity> entityClass, List<UUID> entities) {
if (CollectionUtils.isNotEmpty(entities))
for (UUID id : entities)
remove(entityClass, id);
}
/**
* Same as executeQuery(query, 0, MAX_RESULTS, null).
*/
@Override
@Transactional(readOnly = true)
public final List<Object> executeQuery(String query) {
Assert.hasText(query);
return executeQuery(query, 0, MAX_RESULTS, null);
}
@Transactional
@Override public final int executeUpdate(String update) {
return executeUpdate(update, null);
}
@Transactional(readOnly = true)
@Override public List<Object> executeNativeQuery(String query) {
return executeNativeQuery(query, 0, MAX_RESULTS, null);
}
protected final List<String> getAllIndexedFields(Class<?> clazz, String prefix) {
List<String> fields = new ArrayList<String>();
for (Field f : ClassUtils.getFields(clazz)) {
if (f.getAnnotation(org.hibernate.search.annotations.Field.class) != null) fields.add(prefix + f.getName());
if (f.getAnnotation(IndexedEmbedded.class) != null) {
Class<?> fieldClass = f.getType();
if (Collection.class.isAssignableFrom(fieldClass)) {
ParameterizedType coltype = (ParameterizedType) f.getGenericType();
fields.addAll(getAllIndexedFields((Class<?>) coltype.getActualTypeArguments()[0], prefix + f.getName() + "."));
} else fields.addAll(getAllIndexedFields(fieldClass, prefix + f.getName() + "."));
}
}
return fields;
}
}