Java tutorial
/** * Vulpe Framework - Quick and Smart ;) * Copyright (C) 2011 Active Thread * * Este programa software livre; voc pode redistribu-lo e/ou * modific-lo sob os termos da Licena Pblica Geral GNU, conforme * publicada pela Free Software Foundation; tanto a verso 2 da * Licena como (a seu critrio) qualquer verso mais nova. * * Este programa distribudo na expectativa de ser til, mas SEM * QUALQUER GARANTIA; sem mesmo a garantia implcita de * COMERCIALIZAO ou de ADEQUAO A QUALQUER PROPSITO EM * PARTICULAR. Consulte a Licena Pblica Geral GNU para obter mais * detalhes. * * Voc deve ter recebido uma cpia da Licena Pblica Geral GNU * junto com este programa; se no, escreva para a Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /** * Vulpe Framework - Quick and Smart ;) * Copyright (C) 2011 Active Thread * * 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. */ package org.vulpe.model.dao.impl.db4o; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.persistence.Transient; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.vulpe.commons.util.VulpeDB4OUtil; import org.vulpe.commons.util.VulpeReflectUtil; import org.vulpe.commons.util.VulpeStringUtil; import org.vulpe.exception.VulpeSystemException; import org.vulpe.model.annotations.CreateIfNotExist; import org.vulpe.model.annotations.QueryParameter; import org.vulpe.model.dao.impl.AbstractVulpeBaseDAO; import org.vulpe.model.db4o.annotations.SkipEmpty; import org.vulpe.model.entity.VulpeEntity; import org.vulpe.model.entity.db4o.Identifier; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; /** * Default implementation of DAO for MAIN's with DB4O. * * @author <a href="mailto:felipe@vulpe.org">Geraldo Felipe</a> */ @SuppressWarnings({ "unchecked", "rawtypes" }) public abstract class AbstractVulpeBaseDAODB4O<ENTITY extends VulpeEntity<ID>, ID extends Serializable & Comparable<?>> extends AbstractVulpeBaseDAO<ENTITY, ID> { /* * (non-Javadoc) * * @see org.vulpe.model.dao.VulpeDAO#merge(java.lang.Object) */ public <T> T merge(final T entity) { final ObjectContainer container = getObjectContainer(); try { simpleMerge(container, entity); } catch (Exception e) { rollback(); LOG.error(e.getMessage()); } finally { close(); } return entity; } /** * Merge objects without close transaction. * * @param <T> * @param container * @param entity */ private <T> void simpleMerge(final ObjectContainer container, final T entity) { repairRelationship(load(container, entity), container); container.store(entity); } /** * Get identifier to entity. * * @param <T> * @param entity * @return */ public <T extends VulpeEntity<Long>> Long getId(final Object entity) { final String entityName = entity.getClass().getSimpleName(); final List<Identifier> identifiers = getObjectContainer().queryByExample(new Identifier(entityName)); Identifier identifier = new Identifier(entityName, Long.valueOf(1)); if (identifiers != null && !identifiers.isEmpty()) { identifier = identifiers.get(0); identifier.setSequence(identifier.getSequence() + 1L); } getObjectContainer().store(identifier); return identifier.getSequence(); } /** * Load object by reference. Ignore cache. * * @param <T> * @param container * @param entity * @return */ public <T> T load(final ObjectContainer container, final T entity) { try { final Long identifier = ((VulpeEntity<Long>) entity).getId(); VulpeEntity<Long> entityReferenced = null; if (VulpeEntity.class.isAssignableFrom(entity.getClass()) && identifier == null) { ((VulpeEntity<Long>) entity).setId(getId(entity)); } else { entityReferenced = (VulpeEntity<Long>) entity.getClass().newInstance(); entityReferenced.setId(identifier); entityReferenced = (VulpeEntity<Long>) container.queryByExample(entityReferenced).get(0); container.ext().bind(entity, container.ext().getID(entityReferenced)); } } catch (Exception e) { rollback(); LOG.error(e.getMessage()); } return entity; } /** * Get entity by example. * * @param entity * @return */ public <T extends VulpeEntity<Long>> T getObject(final T entity) { final List<T> list = getList(entity); return list == null ? null : list.get(0); } /** * Get list of entity by example. * * @param entity * @return */ public <T extends VulpeEntity<Long>> List<T> getList(final T entity) { final ObjectContainer container = getObjectContainer(); try { final ObjectSet<T> objectSet = container.queryByExample(entity); final List<T> list = objectSet.hasNext() ? new ArrayList<T>() : null; while (objectSet.hasNext()) { list.add(objectSet.next()); } return list; } finally { rollback(); } } /** * Verified if entity property is empty and set to null; * * @param object */ public void emptyToNull(final Object object) { final List<Field> fields = VulpeReflectUtil.getFields(object.getClass()); for (final Field field : fields) { try { if (field.isAnnotationPresent(SkipEmpty.class)) { continue; } if ((Modifier.isTransient(field.getModifiers()) || field.isAnnotationPresent(Transient.class)) && !field.isAnnotationPresent(QueryParameter.class) && !field.getType().isPrimitive()) { PropertyUtils.setProperty(object, field.getName(), null); } else { final Object value = PropertyUtils.getProperty(object, field.getName()); if (value != null) { if (String.class.isAssignableFrom(field.getType())) { if (StringUtils.isEmpty(value.toString()) || "obj.id".equals(value) || "null".equals(value) /* || "%".equals(value) */) { PropertyUtils.setProperty(object, field.getName(), null); } } else if (VulpeEntity.class.isAssignableFrom(value.getClass()) && !value.getClass().isAnnotationPresent(CreateIfNotExist.class)) { emptyToNull(value); } } } } catch (NoSuchMethodException e) { LOG.debug("Method not found.", e); } catch (Exception e) { throw new VulpeSystemException(e); } } } /** * Repair relationship of entity. * * @param <T> * @param entity */ protected <T> void repairRelationship(final T entity, final ObjectContainer container) { emptyToNull(entity); for (final Field field : VulpeReflectUtil.getFields(entity.getClass())) { if (!Modifier.isTransient(field.getModifiers())) { final Object value = VulpeReflectUtil.getFieldValue(entity, field.getName()); if (value != null) { if (VulpeEntity.class.isAssignableFrom(field.getType())) { try { final VulpeEntity<Long> valueEntity = (VulpeEntity) value; if (valueEntity.getId() != null) { final VulpeEntity<Long> newEntity = (VulpeEntity<Long>) field.getType() .newInstance(); newEntity.setId(valueEntity.getId()); final ObjectSet objectSet = getObjectContainer().queryByExample(newEntity); if (objectSet.hasNext()) { PropertyUtils.setProperty(entity, field.getName(), objectSet.next()); } } else { if (value.getClass().isAnnotationPresent(CreateIfNotExist.class)) { simpleMerge(container, value); } else { PropertyUtils.setProperty(entity, field.getName(), null); } } } catch (Exception e) { LOG.error(e.getMessage()); } } else if (Collection.class.isAssignableFrom(field.getType())) { final Collection details = (Collection) value; for (final Object object : details) { if (object != null) { if (VulpeEntity.class.isAssignableFrom(object.getClass())) { try { final String attributeName = VulpeStringUtil .lowerCaseFirst(entity.getClass().getSimpleName()); final VulpeEntity<Long> detail = (VulpeEntity<Long>) object; repair(detail, container); PropertyUtils.setProperty(detail, attributeName, entity); if (detail.getId() == null) { detail.setId(getId(detail)); } else { final VulpeEntity<Long> valueEntity = (VulpeEntity) entity; final VulpeEntity<Long> newEntity = (VulpeEntity<Long>) entity .getClass().newInstance(); newEntity.setId(valueEntity.getId()); final VulpeEntity<Long> newDetailEntity = (VulpeEntity<Long>) object .getClass().newInstance(); newDetailEntity.setId(detail.getId()); PropertyUtils.setProperty(newDetailEntity, attributeName, newEntity); final ObjectSet objectSet = getObjectContainer() .queryByExample(newDetailEntity); if (objectSet.hasNext()) { final VulpeEntity<Long> persitedDetail = (VulpeEntity<Long>) objectSet .get(0); container.ext().bind(detail, container.ext().getID(persitedDetail)); container.store(detail); } } } catch (Exception e) { LOG.error(e.getMessage()); } } } } } } } } } /** * Repair entity. * * @param <T> * @param entity * @param container * @throws Exception */ public <T> void repair(final T entity, final ObjectContainer container) { for (final Field field : VulpeReflectUtil.getFields(entity.getClass())) { if (VulpeEntity.class.isAssignableFrom(field.getType())) { final VulpeEntity<Long> value = VulpeReflectUtil.getFieldValue(entity, field.getName()); if (value != null) { try { if (value.getId() != null) { final VulpeEntity<Long> newObject = (VulpeEntity<Long>) value.getClass().newInstance(); newObject.setId(value.getId()); final ObjectSet objectSet = getObjectContainer().queryByExample(newObject); if (objectSet.hasNext()) { final VulpeEntity<Long> objectPersisted = (VulpeEntity<Long>) objectSet.get(0); PropertyUtils.setProperty(entity, field.getName(), objectPersisted); } } else { if (value.getClass().isAnnotationPresent(CreateIfNotExist.class)) { simpleMerge(container, value); } else { PropertyUtils.setProperty(entity, field.getName(), null); } } } catch (Exception e) { throw new VulpeSystemException(e); } repair(value, container); } } } } /** * Get instance of Object Container. * * @return returns ObjectContainer. */ public ObjectContainer getObjectContainer() { return VulpeDB4OUtil.getInstance().getObjectContainer(); } /** * Close DB4O instance. */ public void close() { VulpeDB4OUtil.getInstance().close(); } /** * Commit data. */ public void commit() { VulpeDB4OUtil.getInstance().commit(); } /** * Rollback data. */ public void rollback() { VulpeDB4OUtil.getInstance().rollback(); } }