br.gov.jfrj.siga.model.Objeto.java Source code

Java tutorial

Introduction

Here is the source code for br.gov.jfrj.siga.model.Objeto.java

Source

/*******************************************************************************
 * Copyright (c) 2006 - 2011 SJRJ.
 * 
 *     This file is part of SIGA.
 * 
 *     SIGA 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 3 of the License, or
 *     (at your option) any later version.
 * 
 *     SIGA 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 SIGA.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package br.gov.jfrj.siga.model;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.rmi.UnexpectedException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.EntityManager;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PersistenceException;

import org.hibernate.Session;
import org.hibernate.collection.internal.PersistentMap;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.exception.GenericJDBCException;
import org.hibernate.internal.SessionImpl;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;

@MappedSuperclass
public class Objeto extends ObjetoBase {

    //   @Override
    //   public String toString() {
    //      return ClassUtils.toString(this);
    //   }
    //
    //   public boolean equals(Object obj) {
    //      return this == getImplementation(obj);
    //   }

    public static Object getImplementation(Object obj) {
        if (obj instanceof HibernateProxy) {
            return ((HibernateProxy) obj).getHibernateLazyInitializer().getImplementation();
        } else {
            return obj;
        }
    }

    public Object getImplementation() {
        if (this instanceof HibernateProxy) {
            return ((HibernateProxy) this).getHibernateLazyInitializer().getImplementation();
        } else {
            return this;
        }
    }

    @SuppressWarnings("rawtypes")
    public boolean isInstance(Class clazz) {
        return this.getClass().isAssignableFrom(clazz);
    }

    public Objeto unproxy() {
        return this;
    }

    @SuppressWarnings("rawtypes")
    public Objeto unproxyIfInstance(Class clazz) {
        return isInstance(clazz) ? this : null;
    }

    private static final long serialVersionUID = -7830448334427331897L;

    public static EntityManager em() {
        return ContextoPersistencia.em();
    }

    @SuppressWarnings("unchecked")
    public Objeto save() {
        if (!em().contains(this)) {
            em().persist(this);
        }
        avoidCascadeSaveLoops.set(new HashSet<Objeto>());
        try {
            saveAndCascade(true);
        } catch (UnexpectedException e) {
            throw new RuntimeException(e);
        } finally {
            avoidCascadeSaveLoops.get().clear();
        }
        try {
            em().flush();
        } catch (PersistenceException e) {
            if (e.getCause() instanceof GenericJDBCException) {
                throw new PersistenceException(((GenericJDBCException) e.getCause()).getSQL(), e);
            } else {
                throw e;
            }
        }
        avoidCascadeSaveLoops.set(new HashSet<Objeto>());
        try {
            saveAndCascade(false);
        } catch (UnexpectedException e) {
            throw new RuntimeException(e);
        } finally {
            avoidCascadeSaveLoops.get().clear();
        }
        return this;
    }

    @SuppressWarnings("unchecked")
    public Objeto delete() {
        try {
            avoidCascadeSaveLoops.set(new HashSet<Objeto>());
            try {
                saveAndCascade(true);
            } finally {
                avoidCascadeSaveLoops.get().clear();
            }
            em().remove(this);
            try {
                em().flush();
            } catch (PersistenceException e) {
                if (e.getCause() instanceof GenericJDBCException) {
                    throw new PersistenceException(((GenericJDBCException) e.getCause()).getSQL(), e);
                } else {
                    throw e;
                }
            }
            avoidCascadeSaveLoops.set(new HashSet<Objeto>());
            try {
                saveAndCascade(false);
            } finally {
                avoidCascadeSaveLoops.get().clear();
            }
        } catch (PersistenceException e) {
            throw e;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return this;
    }

    public Object _key() {
        Session session = (Session) (em().getDelegate());
        ClassMetadata meta = session.getSessionFactory().getClassMetadata(this.getClass());
        return meta.getIdentifier(this, (SessionImplementor) session);
    }

    // ~~~ SAVING
    public transient boolean willBeSaved = false;
    static transient ThreadLocal<Set<Objeto>> avoidCascadeSaveLoops = new ThreadLocal<Set<Objeto>>();

    @SuppressWarnings("rawtypes")
    private void saveAndCascade(boolean willBeSaved) throws UnexpectedException {
        this.willBeSaved = willBeSaved;
        if (avoidCascadeSaveLoops.get().contains(this)) {
            return;
        } else {
            avoidCascadeSaveLoops.get().add(this);
            if (willBeSaved) {
            }
        }
        // Cascade save
        try {
            Set<Field> fields = new HashSet<Field>();
            Class clazz = this.getClass();
            while (!clazz.equals(Objeto.class)) {
                Collections.addAll(fields, clazz.getDeclaredFields());
                clazz = clazz.getSuperclass();
            }
            for (Field field : fields) {
                field.setAccessible(true);
                if (Modifier.isTransient(field.getModifiers())) {
                    continue;
                }
                boolean doCascade = false;
                if (field.isAnnotationPresent(OneToOne.class)) {
                    doCascade = cascadeAll(field.getAnnotation(OneToOne.class).cascade());
                }
                if (field.isAnnotationPresent(OneToMany.class)) {
                    doCascade = cascadeAll(field.getAnnotation(OneToMany.class).cascade());
                }
                if (field.isAnnotationPresent(ManyToOne.class)) {
                    doCascade = cascadeAll(field.getAnnotation(ManyToOne.class).cascade());
                }
                if (field.isAnnotationPresent(ManyToMany.class)) {
                    doCascade = cascadeAll(field.getAnnotation(ManyToMany.class).cascade());
                }
                if (doCascade) {
                    Object value = field.get(this);
                    if (value != null) {
                        if (value instanceof PersistentMap) {
                            if (((PersistentMap) value).wasInitialized()) {

                                cascadeOrphans(this, (PersistentCollection) value, willBeSaved);

                                for (Object o : ((Map) value).values()) {
                                    saveAndCascadeIfObjeto(o, willBeSaved);
                                }
                            }
                        } else if (value instanceof PersistentCollection) {
                            PersistentCollection col = (PersistentCollection) value;
                            if (((PersistentCollection) value).wasInitialized()) {

                                cascadeOrphans(this, (PersistentCollection) value, willBeSaved);

                                for (Object o : (Collection) value) {
                                    saveAndCascadeIfObjeto(o, willBeSaved);
                                }
                            } else {
                                cascadeOrphans(this, col, willBeSaved);

                                for (Object o : (Collection) value) {
                                    saveAndCascadeIfObjeto(o, willBeSaved);
                                }
                            }
                        } else if (value instanceof Collection) {
                            for (Object o : (Collection) value) {
                                saveAndCascadeIfObjeto(o, willBeSaved);
                            }
                        } else if (value instanceof HibernateProxy && value instanceof Objeto) {
                            if (!((HibernateProxy) value).getHibernateLazyInitializer().isUninitialized()) {
                                ((Objeto) ((HibernateProxy) value).getHibernateLazyInitializer()
                                        .getImplementation()).saveAndCascade(willBeSaved);
                            }
                        } else if (value instanceof Objeto) {
                            ((Objeto) value).saveAndCascade(willBeSaved);
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new UnexpectedException("During cascading save()", e);
        }
    }

    private static void cascadeOrphans(Objeto base, PersistentCollection persistentCollection, boolean willBeSaved)
            throws UnexpectedException {
        SessionImpl session = ((SessionImpl) em().getDelegate());
        PersistenceContext pc = session.getPersistenceContext();
        CollectionEntry ce = pc.getCollectionEntry(persistentCollection);

        if (ce != null) {
            CollectionPersister cp = ce.getLoadedPersister();
            if (cp != null) {
                Type ct = cp.getElementType();
                if (ct instanceof EntityType) {
                    EntityEntry entry = pc.getEntry(base);
                    String entityName = entry.getEntityName();
                    entityName = ((EntityType) ct).getAssociatedEntityName(session.getFactory());
                    if (ce.getSnapshot() != null) {
                        Collection orphans = ce.getOrphans(entityName, persistentCollection);
                        for (Object o : orphans) {
                            saveAndCascadeIfObjeto(o, willBeSaved);
                        }
                    }
                }
            }
        }
    }

    private static void saveAndCascadeIfObjeto(Object o, boolean willBeSaved) throws UnexpectedException {
        if (o instanceof Objeto) {
            ((Objeto) o).saveAndCascade(willBeSaved);
        }
    }

    private static boolean cascadeAll(CascadeType[] types) {
        for (CascadeType cascadeType : types) {
            if (cascadeType == CascadeType.ALL || cascadeType == CascadeType.PERSIST) {
                return true;
            }
        }
        return false;
    }

    public boolean isPersistent() {
        return em().contains(this);
    }

    /**
     * JPASupport instances a and b are equals if either <strong>a == b</strong>
     * or a and b have same </strong>{@link #_key key} and class</strong>
     *
     * @param other
     * @return true if equality condition above is verified
     */
    @Override
    public boolean equals(Object other) {
        final Object key = this._key();

        if (other == null) {
            return false;
        }
        if (this == other) {
            return true;
        }
        if (key == null) {
            return false;
        }
        if (Objeto.class.isAssignableFrom(other.getClass()) && key.getClass().isArray()) {
            Object otherKey = ((Objeto) other)._key();
            if (otherKey.getClass().isArray()) {
                return Arrays.deepEquals((Object[]) key, (Object[]) otherKey);
            }
            return false;
        }

        if (!this.getClass().isAssignableFrom(other.getClass())) {
            return false;
        }

        return key.equals(((Objeto) other)._key());
    }

    @Override
    public int hashCode() {
        final Object key = this._key();
        if (key == null) {
            return 0;
        }
        if (key.getClass().isArray()) {
            return Arrays.deepHashCode((Object[]) key);
        }
        return key.hashCode();
    }

    @Override
    public String toString() {
        final Object key = this._key();
        String keyStr = "";
        if (key != null && key.getClass().isArray()) {
            for (Object object : (Object[]) key) {
                keyStr += object.toString() + ", ";
            }
            keyStr = keyStr.substring(0, keyStr.length() - 2);
        } else if (key != null) {
            keyStr = key.toString();
        }
        return getClass().getSimpleName() + "[" + keyStr + "]";
    }

    @SuppressWarnings("serial")
    public static class JPAQueryException extends RuntimeException {

        public JPAQueryException(String message) {
            super(message);
        }

        public JPAQueryException(String message, Throwable e) {
            super(message + ": " + e.getMessage(), e);
        }

        public static Throwable findBestCause(Throwable e) {
            Throwable best = e;
            Throwable cause = e;
            int it = 0;
            while ((cause = cause.getCause()) != null && it++ < 10) {
                if (cause instanceof ClassCastException) {
                    best = cause;
                    break;
                }
                if (cause instanceof SQLException) {
                    best = cause;
                    break;
                }
            }
            return best;
        }
    }
}