net.navasoft.madcoin.backend.model.controller.impl.EndUsersDataAccess.java Source code

Java tutorial

Introduction

Here is the source code for net.navasoft.madcoin.backend.model.controller.impl.EndUsersDataAccess.java

Source

/*******************************************************************************
    
 * Copyright 2014 Juan Diego Navarre Gonzalez
 * 
 * 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 net.navasoft.madcoin.backend.model.controller.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
import javax.persistence.TypedQuery;

import net.navasoft.madcoin.backend.model.controller.exceptions.AlreadyOnSourceException;
import net.navasoft.madcoin.backend.model.controller.exceptions.IllegalOrphanException;
import net.navasoft.madcoin.backend.model.controller.exceptions.NonexistentEntityException;
import net.navasoft.madcoin.backend.model.controller.exceptions.PreexistingEntityException;
import net.navasoft.madcoin.backend.model.controller.helper.ComplexId;
import net.navasoft.madcoin.backend.model.controller.helper.impl.JPAHelper;
import net.navasoft.madcoin.backend.model.entities.NormalizedEntity;
import net.navasoft.madcoin.backend.model.entities.ReferenceMode;
import net.navasoft.madcoin.backend.model.entities.impl.Administrators;
import net.navasoft.madcoin.backend.model.entities.impl.AppUserXStatus;
import net.navasoft.madcoin.backend.model.entities.impl.AppUsers;
import net.navasoft.madcoin.backend.model.entities.impl.EndUserRankings;
import net.navasoft.madcoin.backend.model.entities.impl.EndUserTypes;
import net.navasoft.madcoin.backend.model.entities.impl.EndUsers;
import net.navasoft.madcoin.backend.model.entities.impl.EndUsersPK;
import net.navasoft.madcoin.backend.model.entities.impl.RequestForData;
import net.navasoft.madcoin.backend.model.entities.impl.SecretQuestions;
import net.navasoft.madcoin.backend.model.entities.impl.UserAuthors;
import net.navasoft.madcoin.backend.model.entities.impl.UserStatus;
import net.navasoft.madcoin.backend.model.entities.impl.WorkRequestsXEndUsers;
import net.navasoft.madcoin.backend.services.rest.impl.IDataAccess;

import org.apache.commons.lang.NotImplementedException;
import org.hibernate.JDBCException;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * net.navasoft.madcoin.backend.model.controller.impl Class class
 * EndUsersDataAccess. Description:
 * 
 * @author Juan Diego Navarre Gonzalez - (${authorMail})
 * @version 1.0
 * @since 2/09/2014 09:31:48 PM
 */
@Repository("endUsersDao")
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class EndUsersDataAccess extends JPAHelper<EndUsers> implements IDataAccess<EndUsers> {

    /**
     * entity manager.
     * 
     * @since 2/09/2014, 09:31:48 PM
     */
    @PersistenceContext(unitName = "ClickNDone-PU")
    private EntityManager entityManager;

    /**
     * app users dao.
     * 
     * @since 2/09/2014, 09:31:48 PM
     */
    @Autowired
    @Qualifier("appUsersDao")
    private IDataAccess<AppUsers> appUsersDao;

    /**
     * user status dao.
     * 
     * @since 2/09/2014, 09:31:48 PM
     */
    @Autowired
    @Qualifier("statusDAO")
    private IDataAccess<AppUserXStatus> userStatusDao;

    /**
     * storage.
     * 
     * @since 2/09/2014, 09:31:48 PM
     */
    private Storage storage;

    /**
     * Instantiates a new end users data access.
     * 
     * @since 2/09/2014, 09:31:48 PM
     */
    public EndUsersDataAccess() {
        storage = StorageFactory.buildStorage();
    }

    /**
     * Gets the all.
     * 
     * @return the all
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public List<EndUsers> getAll() {
        return super.getAllbyQuery(entityManager, EndUsers.class);
    }

    /**
     * Gets the by logical id.
     * 
     * @param idEntity
     *            the id entity
     * @return the by logical id
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public EndUsers getByLogicalId(Serializable idEntity) {
        TypedQuery<EndUsers> query = entityManager.createNamedQuery(
                EndUsers.class.getSimpleName() + "." + NormalizedEntity.NAMED_QUERY_ID, EndUsers.class);
        query.setParameter("appUsername", ((EndUsersPK) idEntity).getAppUsername());
        return query.getSingleResult();
    }

    /**
     * Delete by id.
     * 
     * @param idEntity
     *            the id entity
     * @return the end users
     * @throws NonexistentEntityException
     *             the nonexistent entity exception
     * @throws IllegalOrphanException
     *             the illegal orphan exception
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public EndUsers deleteById(Serializable idEntity) throws NonexistentEntityException, IllegalOrphanException {
        EndUsers deleted = preDelete((EndUsersPK) idEntity);
        entityManager.remove(deleted);
        entityManager.flush();
        return deleted;
    }

    /**
     * Creates the.
     * 
     * @param entity
     *            the entity
     * @return the end users
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { RollbackException.class,
            ConstraintViolationException.class, JDBCException.class })
    public EndUsers create(EndUsers entity) {
        try {
            AppUsers super_user = new AppUsers();
            super_user.setCreatedOn(Calendar.getInstance().getTime());
            super_user = appUsersDao.create(super_user);
            AppUserXStatus statusRef = new AppUserXStatus();
            statusRef.setIdUser(super_user);
            statusRef.setIdUserStatus(new UserStatus(7));
            statusRef = userStatusDao.create(statusRef);
            entity.getEndUsersPK().setIdEndUser(super_user.getIdApplicationUsers());
            entity.setAppUsers(super_user);
            preConstruct(entity);
            entityManager.persist(entity);
            entityManager.flush();
            entity = getByLogicalId(entity.getNormalizedId());
            postConstruct(entity);
        } catch (PersistenceException e) {
            throw new AlreadyOnSourceException(e.getCause().getCause().getMessage());
        } catch (PreexistingEntityException e) {
            throw new AlreadyOnSourceException(e.getMessage());
        }
        return entity;
    }

    /**
     * Delete all.
     * 
     * @throws NonexistentEntityException
     *             the nonexistent entity exception
     * @throws IllegalOrphanException
     *             the illegal orphan exception
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public void deleteAll() throws NonexistentEntityException, IllegalOrphanException {
        for (EndUsers user : getAll()) {
            deleteById(user.getNormalizedId());
        }
    }

    /**
     * Edits the.
     * 
     * @param updatedRecord
     *            the updated record
     * @return the end users
     * @throws NonexistentEntityException
     *             the nonexistent entity exception
     * @throws Exception
     *             the exception
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public EndUsers edit(EndUsers updatedRecord) throws NonexistentEntityException, Exception {
        preEdit(updatedRecord);
        updatedRecord = entityManager.merge(updatedRecord);
        entityManager.flush();
        postEdit(updatedRecord);
        return updatedRecord;
    }

    /**
     * Pre construct.
     * 
     * @param toInsert
     *            the to insert
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public void preConstruct(EndUsers toInsert) {
        if (toInsert.getEndUsersPK() == null) {
            toInsert.setEndUsersPK(new EndUsersPK());
        }
        if (toInsert.getRequestForDataCollection() == null) {
            toInsert.setRequestForDataCollection(new ArrayList<RequestForData>());
        }
        if (toInsert.getWorkRequestsXEndUsersCollection() == null) {
            toInsert.setWorkRequestsXEndUsersCollection(new ArrayList<WorkRequestsXEndUsers>());
        }
        if (toInsert.getUserAuthorsCollection() == null) {
            toInsert.setUserAuthorsCollection(new ArrayList<UserAuthors>());
        }
        if (toInsert.getEndUsersCollection() == null) {
            toInsert.setEndUsersCollection(new ArrayList<EndUsers>());
        }
        if (toInsert.getEndUserRankingsCollection() == null) {
            toInsert.setEndUserRankingsCollection(new ArrayList<EndUserRankings>());
        }

        toInsert.getEndUsersPK().setIdEndUser(toInsert.getAppUsers().getIdApplicationUsers());

        EndUsers endUsersRel = toInsert.getEndUsers();
        if (endUsersRel != null) {
            endUsersRel = entityManager.find(EndUsers.class, endUsersRel.getEndUsersPK());
            toInsert.setEndUsers(endUsersRel);
            storage.storeReference(EndUsersStorageKeys.USER_LAST_UPDATED, ReferenceMode.NEW_REFERENCE, endUsersRel);
        }
        EndUserTypes idUserType = toInsert.getIdUserType();
        if (idUserType != null) {
            idUserType = entityManager.getReference(idUserType.getClass(), idUserType.getIdEndUserPrivileges());
            toInsert.setIdUserType(idUserType);
            storage.storeReference(EndUsersStorageKeys.END_USER_TYPE, ReferenceMode.NEW_REFERENCE, idUserType);
        }
        SecretQuestions idSecretQuestion = toInsert.getIdSecretQuestion();
        if (idSecretQuestion != null) {
            idSecretQuestion = entityManager.getReference(idSecretQuestion.getClass(),
                    idSecretQuestion.getIdSecretQuestionUser());
            toInsert.setIdSecretQuestion(idSecretQuestion);
            storage.storeReference(EndUsersStorageKeys.HELPER_QUESTION, ReferenceMode.NEW_REFERENCE,
                    idSecretQuestion);
        }
        AppUsers appUsers = toInsert.getAppUsers();
        if (appUsers != null) {
            appUsers = entityManager.getReference(appUsers.getClass(), appUsers.getIdApplicationUsers());
            toInsert.setAppUsers(appUsers);
            storage.storeReference(EndUsersStorageKeys.SUPERTYPE, ReferenceMode.NEW_REFERENCE, appUsers);
        }
        Administrators administrators = toInsert.getAdministrators();
        if (administrators != null) {
            administrators = entityManager.getReference(administrators.getClass(),
                    administrators.getAdministratorsPK());
            toInsert.setAdministrators(administrators);
            storage.storeReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED, ReferenceMode.NEW_REFERENCE,
                    administrators);
        }
        Collection<RequestForData> attachedRequestForDataCollection = new ArrayList<RequestForData>();
        for (RequestForData requestForDataCollectionRequestForDataToAttach : toInsert
                .getRequestForDataCollection()) {
            requestForDataCollectionRequestForDataToAttach = entityManager.getReference(
                    requestForDataCollectionRequestForDataToAttach.getClass(),
                    requestForDataCollectionRequestForDataToAttach.getIdRequestForData());
            attachedRequestForDataCollection.add(requestForDataCollectionRequestForDataToAttach);
        }
        toInsert.setRequestForDataCollection(attachedRequestForDataCollection);

        Collection<WorkRequestsXEndUsers> attachedWorkRequestsXEndUsersCollection = new ArrayList<WorkRequestsXEndUsers>();
        for (WorkRequestsXEndUsers workRequestsXEndUsersCollectionWorkRequestsXEndUsersToAttach : toInsert
                .getWorkRequestsXEndUsersCollection()) {
            workRequestsXEndUsersCollectionWorkRequestsXEndUsersToAttach = entityManager.getReference(
                    workRequestsXEndUsersCollectionWorkRequestsXEndUsersToAttach.getClass(),
                    workRequestsXEndUsersCollectionWorkRequestsXEndUsersToAttach.getWorkRequestsXEndUsersPK());
            attachedWorkRequestsXEndUsersCollection
                    .add(workRequestsXEndUsersCollectionWorkRequestsXEndUsersToAttach);
        }
        toInsert.setWorkRequestsXEndUsersCollection(attachedWorkRequestsXEndUsersCollection);

        Collection<UserAuthors> attachedUserAuthorsCollection = new ArrayList<UserAuthors>();
        for (UserAuthors userAuthorsCollectionUserAuthorsToAttach : toInsert.getUserAuthorsCollection()) {
            userAuthorsCollectionUserAuthorsToAttach.setEndUsers(toInsert);
            entityManager.persist(userAuthorsCollectionUserAuthorsToAttach);
            userAuthorsCollectionUserAuthorsToAttach.setIdUserAuthors(entityManager
                    .createNamedQuery(userAuthorsCollectionUserAuthorsToAttach.getNamedQueryId(), UserAuthors.class)
                    .getSingleResult().getIdUserAuthors());
            userAuthorsCollectionUserAuthorsToAttach = entityManager.getReference(
                    userAuthorsCollectionUserAuthorsToAttach.getClass(),
                    userAuthorsCollectionUserAuthorsToAttach.getIdUserAuthors());
            attachedUserAuthorsCollection.add(userAuthorsCollectionUserAuthorsToAttach);
        }
        toInsert.setUserAuthorsCollection(attachedUserAuthorsCollection);

        Collection<EndUsers> attachedEndUsersCollection = new ArrayList<EndUsers>();
        for (EndUsers endUsersCollectionEndUsersToAttach : toInsert.getEndUsersCollection()) {
            endUsersCollectionEndUsersToAttach = entityManager.getReference(EndUsers.class,
                    endUsersCollectionEndUsersToAttach.getEndUsersPK());
            attachedEndUsersCollection.add(endUsersCollectionEndUsersToAttach);
        }
        toInsert.setEndUsersCollection(attachedEndUsersCollection);

        Collection<EndUserRankings> attachedEndUserRankingsCollection = new ArrayList<EndUserRankings>();
        for (EndUserRankings endUserRankingsCollectionEndUserRankingsToAttach : toInsert
                .getEndUserRankingsCollection()) {
            endUserRankingsCollectionEndUserRankingsToAttach = entityManager.getReference(
                    endUserRankingsCollectionEndUserRankingsToAttach.getClass(),
                    endUserRankingsCollectionEndUserRankingsToAttach.getIdendUserRanking());
            attachedEndUserRankingsCollection.add(endUserRankingsCollectionEndUserRankingsToAttach);
        }
        toInsert.setEndUserRankingsCollection(attachedEndUserRankingsCollection);
    }

    /**
     * Post construct.
     * 
     * @param inserted
     *            the inserted
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public void postConstruct(EndUsers inserted) {
        EndUsers endUsersRel;
        EndUserTypes idUserType;
        SecretQuestions idSecretQuestion;
        AppUsers appUsers;
        Administrators administrators;

        if (storage.validateReference(EndUsersStorageKeys.USER_LAST_UPDATED, ReferenceMode.NEW_REFERENCE)) {
            endUsersRel = (EndUsers) storage.extractReference(EndUsersStorageKeys.USER_LAST_UPDATED,
                    ReferenceMode.NEW_REFERENCE);
            endUsersRel.getEndUsersCollection().add(inserted);
            endUsersRel = entityManager.merge(endUsersRel);
        }
        if (storage.validateReference(EndUsersStorageKeys.END_USER_TYPE, ReferenceMode.NEW_REFERENCE)) {
            idUserType = (EndUserTypes) storage.extractReference(EndUsersStorageKeys.END_USER_TYPE,
                    ReferenceMode.NEW_REFERENCE);
            idUserType.getEndUsersCollection().add(inserted);
            idUserType = entityManager.merge(idUserType);
        }
        if (storage.validateReference(EndUsersStorageKeys.HELPER_QUESTION, ReferenceMode.NEW_REFERENCE)) {
            idSecretQuestion = (SecretQuestions) storage.extractReference(EndUsersStorageKeys.HELPER_QUESTION,
                    ReferenceMode.NEW_REFERENCE);
            idSecretQuestion.getEndUsersCollection().add(inserted);
            idSecretQuestion = entityManager.merge(idSecretQuestion);
        }
        if (storage.validateReference(EndUsersStorageKeys.SUPERTYPE, ReferenceMode.NEW_REFERENCE)) {
            appUsers = (AppUsers) storage.extractReference(EndUsersStorageKeys.SUPERTYPE,
                    ReferenceMode.NEW_REFERENCE);
            appUsers.getEndUsersCollection().add(inserted);
            appUsers = entityManager.merge(appUsers);
        }
        if (storage.validateReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED, ReferenceMode.NEW_REFERENCE)) {
            administrators = (Administrators) storage.extractReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED,
                    ReferenceMode.NEW_REFERENCE);
            administrators.getEndUsersCollection().add(inserted);
            administrators = entityManager.merge(administrators);
        }
        for (RequestForData dataRequest : inserted.getRequestForDataCollection()) {
            EndUsers oldDataRequest = dataRequest.getEndUsers();
            dataRequest.setEndUsers(inserted);
            dataRequest = entityManager.merge(dataRequest);
            if (oldDataRequest != null) {
                oldDataRequest.getRequestForDataCollection().remove(dataRequest);
                oldDataRequest = entityManager.merge(oldDataRequest);
            }
        }
        for (WorkRequestsXEndUsers requestedOrder : inserted.getWorkRequestsXEndUsersCollection()) {
            EndUsers oldRequestedOrder = requestedOrder.getEndUsers();
            requestedOrder.setEndUsers(inserted);
            requestedOrder = entityManager.merge(requestedOrder);
            if (oldRequestedOrder != null) {
                oldRequestedOrder.getWorkRequestsXEndUsersCollection().remove(requestedOrder);
                oldRequestedOrder = entityManager.merge(oldRequestedOrder);
            }
        }
        for (UserAuthors originData : inserted.getUserAuthorsCollection()) {
            EndUsers oldOriginData = originData.getEndUsers();
            originData.setEndUsers(inserted);
            originData = entityManager.merge(originData);
            if (oldOriginData != null) {
                oldOriginData.getUserAuthorsCollection().remove(originData);
                oldOriginData = entityManager.merge(oldOriginData);
            }
        }
        for (EndUsers selfReference : inserted.getEndUsersCollection()) {
            EndUsers oldReference = selfReference.getEndUsers();
            selfReference.setEndUsers(inserted);
            selfReference = entityManager.merge(selfReference);
            if (oldReference != null) {
                oldReference.getEndUsersCollection().remove(selfReference);
                oldReference = entityManager.merge(oldReference);
            }
        }
        for (EndUserRankings scoring : inserted.getEndUserRankingsCollection()) {
            EndUsers oldScoring = scoring.getEndUsers();
            scoring.setEndUsers(inserted);
            scoring = entityManager.merge(scoring);
            if (oldScoring != null) {
                oldScoring.getEndUserRankingsCollection().remove(scoring);
                oldScoring = entityManager.merge(oldScoring);
            }
        }
    }

    /**
     * Pre delete.
     * 
     * @param toDelete
     *            the to delete
     * @return the end users
     * @throws NonexistentEntityException
     *             the nonexistent entity exception
     * @throws IllegalOrphanException
     *             the illegal orphan exception
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public EndUsers preDelete(Number toDelete) throws NonexistentEntityException, IllegalOrphanException {
        throw new NotImplementedException();
    }

    /**
     * Pre delete.
     * 
     * @param toDelete
     *            the to delete
     * @return the end users
     * @throws NonexistentEntityException
     *             the nonexistent entity exception
     * @throws IllegalOrphanException
     *             the illegal orphan exception
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public EndUsers preDelete(ComplexId toDelete) throws NonexistentEntityException, IllegalOrphanException {
        EndUsers removable = entityManager.find(EndUsers.class, toDelete);
        List<String> illegalOrphanMessages = null;

        Collection<RequestForData> dataRequestsCheck = removable.getRequestForDataCollection();
        for (RequestForData dataRequestCheck : dataRequestsCheck) {
            if (illegalOrphanMessages == null) {
                illegalOrphanMessages = new ArrayList<String>();
            }
            illegalOrphanMessages.add("This EndUsers (" + removable
                    + ") cannot be destroyed since the RequestForData " + dataRequestCheck
                    + " in its requestForDataCollection field has a non-nullable endUsers field.");
        }
        Collection<WorkRequestsXEndUsers> servicesRequested = removable.getWorkRequestsXEndUsersCollection();
        for (WorkRequestsXEndUsers serviceRequested : servicesRequested) {
            if (illegalOrphanMessages == null) {
                illegalOrphanMessages = new ArrayList<String>();
            }
            illegalOrphanMessages.add("This EndUsers (" + removable
                    + ") cannot be destroyed since the WorkRequestsXEndUsers " + serviceRequested
                    + " in its workRequestsXEndUsersCollection field has a non-nullable endUsers field.");
        }
        Collection<UserAuthors> originsData = removable.getUserAuthorsCollection();
        for (UserAuthors originData : originsData) {
            if (illegalOrphanMessages == null) {
                illegalOrphanMessages = new ArrayList<String>();
            }
            illegalOrphanMessages.add("This EndUsers (" + removable + ") cannot be destroyed since the UserAuthors "
                    + originData + " in its userAuthorsCollection field has a non-nullable endUsers field.");
        }
        if (illegalOrphanMessages != null) {
            throw new IllegalOrphanException(illegalOrphanMessages);
        }

        EndUsers endUsersRel = removable.getEndUsers();
        if (endUsersRel != null) {
            endUsersRel.getEndUsersCollection().remove(removable);
            endUsersRel = entityManager.merge(endUsersRel);
        }
        EndUserTypes idUserType = removable.getIdUserType();
        if (idUserType != null) {
            idUserType.getEndUsersCollection().remove(removable);
            idUserType = entityManager.merge(idUserType);
        }
        SecretQuestions idSecretQuestion = removable.getIdSecretQuestion();
        if (idSecretQuestion != null) {
            idSecretQuestion.getEndUsersCollection().remove(removable);
            idSecretQuestion = entityManager.merge(idSecretQuestion);
        }
        AppUsers appUsers = removable.getAppUsers();
        if (appUsers != null) {
            appUsers.getEndUsersCollection().remove(removable);
            appUsers = entityManager.merge(appUsers);
        }
        Administrators administrators = removable.getAdministrators();
        if (administrators != null) {
            administrators.getEndUsersCollection().remove(removable);
            administrators = entityManager.merge(administrators);
        }
        Collection<EndUsers> endUsersCollection = removable.getEndUsersCollection();
        for (EndUsers endUsersCollectionEndUsers : endUsersCollection) {
            endUsersCollectionEndUsers.setEndUsers(null);
            endUsersCollectionEndUsers = entityManager.merge(endUsersCollectionEndUsers);
        }
        Collection<EndUserRankings> endUserRankingsCollection = removable.getEndUserRankingsCollection();
        for (EndUserRankings endUserRankingsCollectionEndUserRankings : endUserRankingsCollection) {
            endUserRankingsCollectionEndUserRankings.setEndUsers(null);
            endUserRankingsCollectionEndUserRankings = entityManager
                    .merge(endUserRankingsCollectionEndUserRankings);
        }
        return removable;
    }

    /**
     * Pre edit.
     * 
     * @param toEdit
     *            the to edit
     * @throws NonexistentEntityException
     *             the nonexistent entity exception
     * @throws IllegalOrphanException
     *             the illegal orphan exception
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public void preEdit(EndUsers toEdit) throws NonexistentEntityException, IllegalOrphanException {
        toEdit.getEndUsersPK().setIdEndUser(toEdit.getAppUsers().getIdApplicationUsers());
        EndUsers persistentEndUsers = findByComplexId(entityManager, toEdit.getEndUsersPK(), EndUsers.class);
        EndUsers endUsersRelOld = persistentEndUsers.getEndUsers();
        storage.storeReference(EndUsersStorageKeys.USER_LAST_UPDATED, ReferenceMode.OLD_REFERENCE, endUsersRelOld);

        EndUsers endUsersRelNew = toEdit.getEndUsers();

        EndUserTypes idUserTypeOld = persistentEndUsers.getIdUserType();
        storage.storeReference(EndUsersStorageKeys.END_USER_TYPE, ReferenceMode.OLD_REFERENCE, idUserTypeOld);

        EndUserTypes idUserTypeNew = toEdit.getIdUserType();

        SecretQuestions idSecretQuestionOld = persistentEndUsers.getIdSecretQuestion();
        storage.storeReference(EndUsersStorageKeys.HELPER_QUESTION, ReferenceMode.OLD_REFERENCE,
                idSecretQuestionOld);

        SecretQuestions idSecretQuestionNew = toEdit.getIdSecretQuestion();

        AppUsers appUsersOld = persistentEndUsers.getAppUsers();
        storage.storeReference(EndUsersStorageKeys.SUPERTYPE, ReferenceMode.OLD_REFERENCE, appUsersOld);

        AppUsers appUsersNew = toEdit.getAppUsers();

        Administrators administratorsOld = persistentEndUsers.getAdministrators();
        storage.storeReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED, ReferenceMode.OLD_REFERENCE,
                administratorsOld);
        Administrators administratorsNew = toEdit.getAdministrators();

        Collection<RequestForData> oldViews = persistentEndUsers.getRequestForDataCollection();
        storage.storeReference(EndUsersStorageKeys.INFORMATION_REQUEST, ReferenceMode.OLD_REFERENCE, oldViews);
        Collection<RequestForData> newViews = toEdit.getRequestForDataCollection();

        Collection<WorkRequestsXEndUsers> oldHistory = persistentEndUsers.getWorkRequestsXEndUsersCollection();
        storage.storeReference(EndUsersStorageKeys.SERVICE_HISTORY, ReferenceMode.OLD_REFERENCE, oldHistory);
        Collection<WorkRequestsXEndUsers> newHistory = toEdit.getWorkRequestsXEndUsersCollection();

        Collection<UserAuthors> oldCreations = persistentEndUsers.getUserAuthorsCollection();
        storage.storeReference(EndUsersStorageKeys.USER_AUTHORS, ReferenceMode.OLD_REFERENCE, oldHistory);

        Collection<UserAuthors> newCreation = toEdit.getUserAuthorsCollection();

        Collection<EndUsers> endUsersCollectionOld = persistentEndUsers.getEndUsersCollection();
        storage.storeReference(EndUsersStorageKeys.SELF, ReferenceMode.OLD_REFERENCE, endUsersCollectionOld);

        Collection<EndUsers> endUsersCollectionNew = toEdit.getEndUsersCollection();

        Collection<EndUserRankings> endUserRankingsCollectionOld = persistentEndUsers
                .getEndUserRankingsCollection();
        storage.storeReference(EndUsersStorageKeys.SCORING, ReferenceMode.OLD_REFERENCE,
                endUserRankingsCollectionOld);

        Collection<EndUserRankings> endUserRankingsCollectionNew = toEdit.getEndUserRankingsCollection();

        List<String> illegalOrphanMessages = null;
        for (RequestForData oldView : oldViews) {
            if (!newViews.contains(oldView)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add(
                        "You must retain RequestForData " + oldView + " since its endUsers field is not nullable.");
            }
        }
        for (WorkRequestsXEndUsers oldService : oldHistory) {
            if (!newHistory.contains(oldService)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain WorkRequestsXEndUsers " + oldService
                        + " since its endUsers field is not nullable.");
            }
        }
        for (UserAuthors oldCreation : oldCreations) {
            if (!newCreation.contains(oldCreation)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain UserAuthors " + oldCreations
                        + " since its endUsers field is not nullable.");
            }
        }
        if (illegalOrphanMessages != null) {
            throw new IllegalOrphanException(illegalOrphanMessages);
        }
        if (endUsersRelNew != null) {
            endUsersRelNew = entityManager.getReference(EndUsers.class, endUsersRelNew.getEndUsersPK());
            toEdit.setEndUsers(endUsersRelNew);
            storage.storeReference(EndUsersStorageKeys.USER_LAST_UPDATED, ReferenceMode.NEW_REFERENCE,
                    endUsersRelNew);
        }
        if (idUserTypeNew != null) {
            idUserTypeNew = entityManager.getReference(idUserTypeNew.getClass(),
                    idUserTypeNew.getIdEndUserPrivileges());
            toEdit.setIdUserType(idUserTypeNew);
            storage.storeReference(EndUsersStorageKeys.END_USER_TYPE, ReferenceMode.NEW_REFERENCE, idUserTypeNew);
        }
        if (idSecretQuestionNew != null) {
            idSecretQuestionNew = entityManager.getReference(idSecretQuestionNew.getClass(),
                    idSecretQuestionNew.getIdSecretQuestionUser());
            toEdit.setIdSecretQuestion(idSecretQuestionNew);
            storage.storeReference(EndUsersStorageKeys.HELPER_QUESTION, ReferenceMode.NEW_REFERENCE, idUserTypeNew);
        }
        if (appUsersNew != null) {
            appUsersNew = entityManager.getReference(appUsersNew.getClass(), appUsersNew.getIdApplicationUsers());
            toEdit.setAppUsers(appUsersNew);
            storage.storeReference(EndUsersStorageKeys.SUPERTYPE, ReferenceMode.NEW_REFERENCE, appUsersNew);
        }
        if (administratorsNew != null) {
            administratorsNew = entityManager.getReference(administratorsNew.getClass(),
                    administratorsNew.getAdministratorsPK());
            toEdit.setAdministrators(administratorsNew);
            storage.storeReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED, ReferenceMode.NEW_REFERENCE,
                    administratorsNew);
        }

        Collection<RequestForData> auxNewViews = new ArrayList<RequestForData>();
        for (RequestForData newView : newViews) {
            newView = entityManager.getReference(newView.getClass(), newView.getIdRequestForData());
            auxNewViews.add(newView);
        }
        newViews = auxNewViews;
        toEdit.setRequestForDataCollection(newViews);
        storage.storeReference(EndUsersStorageKeys.INFORMATION_REQUEST, ReferenceMode.NEW_REFERENCE, newViews);

        Collection<WorkRequestsXEndUsers> newServices = new ArrayList<WorkRequestsXEndUsers>();
        for (WorkRequestsXEndUsers newService : newHistory) {
            newService = entityManager.getReference(newService.getClass(), newService.getWorkRequestsXEndUsersPK());
            newServices.add(newService);
        }
        newHistory = newServices;
        toEdit.setWorkRequestsXEndUsersCollection(newHistory);
        storage.storeReference(EndUsersStorageKeys.SERVICE_HISTORY, ReferenceMode.NEW_REFERENCE, newHistory);

        Collection<UserAuthors> creators = new ArrayList<UserAuthors>();
        for (UserAuthors creator : newCreation) {
            creator = entityManager.getReference(creator.getClass(), creator.getIdUserAuthors());
            creators.add(creator);
        }
        newCreation = creators;
        toEdit.setUserAuthorsCollection(newCreation);
        storage.storeReference(EndUsersStorageKeys.USER_AUTHORS, ReferenceMode.NEW_REFERENCE, newCreation);

        Collection<EndUsers> selves = new ArrayList<EndUsers>();
        for (EndUsers self : endUsersCollectionNew) {
            self = entityManager.getReference(self.getClass(), self.getEndUsersPK());
            selves.add(self);
        }
        endUsersCollectionNew = selves;
        toEdit.setEndUsersCollection(endUsersCollectionNew);
        storage.storeReference(EndUsersStorageKeys.SELF, ReferenceMode.NEW_REFERENCE, endUsersCollectionNew);

        Collection<EndUserRankings> scores = new ArrayList<EndUserRankings>();
        for (EndUserRankings score : endUserRankingsCollectionNew) {
            score = entityManager.getReference(score.getClass(), score.getIdendUserRanking());
            scores.add(score);
        }
        endUserRankingsCollectionNew = scores;
        toEdit.setEndUserRankingsCollection(endUserRankingsCollectionNew);
        storage.storeReference(EndUsersStorageKeys.SCORING, ReferenceMode.NEW_REFERENCE,
                endUserRankingsCollectionNew);
    }

    /**
     * Post edit.
     * 
     * @param entity
     *            the entity
     * @since 2/09/2014, 09:31:48 PM
     */
    @SuppressWarnings("unchecked")
    @Override
    public void postEdit(EndUsers entity) {
        EndUsers endUsersRelOld;
        EndUsers endUsersRelNew;
        EndUserTypes idUserTypeOld;
        EndUserTypes idUserTypeNew;
        SecretQuestions idSecretQuestionOld;
        SecretQuestions idSecretQuestionNew;
        AppUsers appUsersOld;
        AppUsers appUsersNew;
        Administrators administratorsOld;
        Administrators administratorsNew;

        if (storage.compareReferences(EndUsersStorageKeys.USER_LAST_UPDATED, ReferenceMode.OLD_REFERENCE)) {
            endUsersRelOld = (EndUsers) storage.extractReference(EndUsersStorageKeys.USER_LAST_UPDATED,
                    ReferenceMode.OLD_REFERENCE);
            endUsersRelOld.getEndUsersCollection().remove(entity);
            endUsersRelOld = entityManager.merge(endUsersRelOld);
        }
        if (storage.compareReferences(EndUsersStorageKeys.USER_LAST_UPDATED, ReferenceMode.NEW_REFERENCE)) {
            endUsersRelNew = (EndUsers) storage.extractReference(EndUsersStorageKeys.USER_LAST_UPDATED,
                    ReferenceMode.NEW_REFERENCE);
            endUsersRelNew.getEndUsersCollection().add(entity);
            endUsersRelNew = entityManager.merge(endUsersRelNew);
        }
        if (storage.compareReferences(EndUsersStorageKeys.END_USER_TYPE, ReferenceMode.OLD_REFERENCE)) {
            idUserTypeOld = (EndUserTypes) storage.extractReference(EndUsersStorageKeys.END_USER_TYPE,
                    ReferenceMode.OLD_REFERENCE);
            idUserTypeOld.getEndUsersCollection().remove(entity);
            idUserTypeOld = entityManager.merge(idUserTypeOld);
        }
        if (storage.compareReferences(EndUsersStorageKeys.END_USER_TYPE, ReferenceMode.NEW_REFERENCE)) {
            idUserTypeNew = (EndUserTypes) storage.extractReference(EndUsersStorageKeys.END_USER_TYPE,
                    ReferenceMode.NEW_REFERENCE);
            idUserTypeNew.getEndUsersCollection().add(entity);
            idUserTypeNew = entityManager.merge(idUserTypeNew);
        }
        if (storage.validateReference(EndUsersStorageKeys.HELPER_QUESTION, ReferenceMode.OLD_REFERENCE)) {
            idSecretQuestionOld = (SecretQuestions) storage.extractReference(EndUsersStorageKeys.HELPER_QUESTION,
                    ReferenceMode.OLD_REFERENCE);
            idSecretQuestionOld.getEndUsersCollection().remove(entity);
            idSecretQuestionOld = entityManager.merge(idSecretQuestionOld);
        }
        if (storage.validateReference(EndUsersStorageKeys.HELPER_QUESTION, ReferenceMode.NEW_REFERENCE)) {
            idSecretQuestionNew = (SecretQuestions) storage.extractReference(EndUsersStorageKeys.HELPER_QUESTION,
                    ReferenceMode.NEW_REFERENCE);
            idSecretQuestionNew.getEndUsersCollection().add(entity);
            idSecretQuestionNew = entityManager.merge(idSecretQuestionNew);
        }
        if (storage.compareReferences(EndUsersStorageKeys.SUPERTYPE, ReferenceMode.OLD_REFERENCE)) {
            appUsersOld = (AppUsers) storage.extractReference(EndUsersStorageKeys.SUPERTYPE,
                    ReferenceMode.OLD_REFERENCE);
            appUsersOld.getEndUsersCollection().remove(entity);
            appUsersOld = entityManager.merge(appUsersOld);
        }
        if (storage.compareReferences(EndUsersStorageKeys.SUPERTYPE, ReferenceMode.NEW_REFERENCE)) {
            appUsersNew = (AppUsers) storage.extractReference(EndUsersStorageKeys.SUPERTYPE,
                    ReferenceMode.NEW_REFERENCE);
            appUsersNew.getEndUsersCollection().add(entity);
            appUsersNew = entityManager.merge(appUsersNew);
        }
        if (storage.compareReferences(EndUsersStorageKeys.ADMIN_LAST_UPDATED, ReferenceMode.OLD_REFERENCE)) {
            administratorsOld = (Administrators) storage.extractReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED,
                    ReferenceMode.OLD_REFERENCE);
            administratorsOld.getEndUsersCollection().remove(entity);
            administratorsOld = entityManager.merge(administratorsOld);
        }
        if (storage.compareReferences(EndUsersStorageKeys.ADMIN_LAST_UPDATED, ReferenceMode.NEW_REFERENCE)) {
            administratorsNew = (Administrators) storage.extractReference(EndUsersStorageKeys.ADMIN_LAST_UPDATED,
                    ReferenceMode.NEW_REFERENCE);
            administratorsNew.getEndUsersCollection().add(entity);
            administratorsNew = entityManager.merge(administratorsNew);
        }

        Collection<RequestForData> newRequestsForData = (Collection<RequestForData>) storage
                .extractReferences(EndUsersStorageKeys.INFORMATION_REQUEST, ReferenceMode.NEW_REFERENCE);
        Collection<RequestForData> oldRequestsForData = (Collection<RequestForData>) storage
                .extractReference(EndUsersStorageKeys.INFORMATION_REQUEST, ReferenceMode.OLD_REFERENCE);
        for (RequestForData newDataRequested : newRequestsForData) {
            if (!oldRequestsForData.contains(newDataRequested)) {
                EndUsers oldDataRequested = newDataRequested.getEndUsers();
                newDataRequested.setEndUsers(entity);
                newDataRequested = entityManager.merge(newDataRequested);
                if (oldDataRequested != null && !oldDataRequested.equals(entity)) {
                    oldDataRequested.getRequestForDataCollection().remove(newDataRequested);
                    oldDataRequested = entityManager.merge(oldDataRequested);
                }
            }
        }

        Collection<WorkRequestsXEndUsers> newServicesRequested = (Collection<WorkRequestsXEndUsers>) storage
                .extractReferences(EndUsersStorageKeys.SERVICE_HISTORY, ReferenceMode.NEW_REFERENCE);
        Collection<WorkRequestsXEndUsers> oldServicesRequested = (Collection<WorkRequestsXEndUsers>) storage
                .extractReference(EndUsersStorageKeys.SERVICE_HISTORY, ReferenceMode.OLD_REFERENCE);
        for (WorkRequestsXEndUsers newServiceRequested : newServicesRequested) {
            if (!oldServicesRequested.contains(newServiceRequested)) {
                EndUsers oldServiceRequester = newServiceRequested.getEndUsers();
                newServiceRequested.setEndUsers(entity);
                newServiceRequested = entityManager.merge(newServiceRequested);
                if (oldServiceRequester != null && !oldServiceRequester.equals(entity)) {
                    oldServiceRequester.getWorkRequestsXEndUsersCollection().remove(newServiceRequested);
                    oldServiceRequester = entityManager.merge(oldServiceRequester);
                }
            }
        }

        Collection<UserAuthors> newOrigins = (Collection<UserAuthors>) storage
                .extractReferences(EndUsersStorageKeys.USER_AUTHORS, ReferenceMode.NEW_REFERENCE);
        Collection<UserAuthors> oldOrigins = (Collection<UserAuthors>) storage
                .extractReference(EndUsersStorageKeys.USER_AUTHORS, ReferenceMode.OLD_REFERENCE);
        for (UserAuthors newOrigin : newOrigins) {
            if (!oldOrigins.contains(newOrigin)) {
                EndUsers oldOriginator = newOrigin.getEndUsers();
                newOrigin.setEndUsers(entity);
                newOrigin = entityManager.merge(newOrigin);
                if (oldOriginator != null && !oldOriginator.equals(entity)) {
                    oldOriginator.getUserAuthorsCollection().remove(newOrigin);
                    oldOriginator = entityManager.merge(oldOriginator);
                }
            }
        }

        Collection<EndUsers> newSelves = (Collection<EndUsers>) storage.extractReferences(EndUsersStorageKeys.SELF,
                ReferenceMode.NEW_REFERENCE);
        Collection<EndUsers> oldSelves = (Collection<EndUsers>) storage.extractReference(EndUsersStorageKeys.SELF,
                ReferenceMode.OLD_REFERENCE);

        for (EndUsers oldSelf : oldSelves) {
            if (!newSelves.contains(oldSelf)) {
                oldSelf.setEndUsers(null);
                oldSelf = entityManager.merge(oldSelf);
            }
        }
        for (EndUsers newSelf : newSelves) {
            if (!oldSelves.contains(newSelf)) {
                EndUsers referrance = newSelf.getEndUsers();
                newSelf.setEndUsers(entity);
                newSelf = entityManager.merge(newSelf);
                if (referrance != null && !referrance.equals(entity)) {
                    referrance.getEndUsersCollection().remove(newSelf);
                    referrance = entityManager.merge(referrance);
                }
            }
        }

        Collection<EndUserRankings> newRanks = (Collection<EndUserRankings>) storage
                .extractReferences(EndUsersStorageKeys.SCORING, ReferenceMode.NEW_REFERENCE);
        Collection<EndUserRankings> oldRanks = (Collection<EndUserRankings>) storage
                .extractReference(EndUsersStorageKeys.SCORING, ReferenceMode.OLD_REFERENCE);

        for (EndUserRankings oldRank : oldRanks) {
            if (!newRanks.contains(oldRank)) {
                oldRank.setEndUsers(null);
                oldRank = entityManager.merge(oldRank);
            }
        }
        for (EndUserRankings newRank : newRanks) {
            if (!oldRanks.contains(newRank)) {
                EndUsers referrance = newRank.getEndUsers();
                newRank.setEndUsers(entity);
                newRank = entityManager.merge(newRank);
                if (referrance != null && !referrance.equals(entity)) {
                    referrance.getEndUserRankingsCollection().remove(newRank);
                    referrance = entityManager.merge(referrance);
                }
            }
        }
        storage.clean();
    }

    /**
     * net.navasoft.madcoin.backend.model.controller.impl Enum enum
     * EndUsersStorageKeys. Description:
     * 
     * @author Juan Diego Navarre Gonzalez - (${authorMail})
     * @version 1.0
     * @since 2/09/2014 09:31:48 PM
     */
    private enum EndUsersStorageKeys implements StorageKeys {

        /**
         * user last updated.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        USER_LAST_UPDATED("EndUsersRel"),

        /**
         * end user type.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        END_USER_TYPE("IdUserType"),

        /**
         * helper question.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        HELPER_QUESTION("IdSecretQuestion"),

        /**
         * supertype.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        SUPERTYPE("AppUsers"),

        /**
         * admin last updated.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        ADMIN_LAST_UPDATED("Administrators"),

        /**
         * information request.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        INFORMATION_REQUEST("RequestsForData"),

        /**
         * service history.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        SERVICE_HISTORY("ServicesRequested"),

        /**
         * user authors.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        USER_AUTHORS("OriginData"),

        /**
         * self.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        SELF("SelfReferences"),

        /**
         * scoring.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        SCORING("Rankings");

        /**
         * key.
         * 
         * @since 2/09/2014, 09:31:48 PM
         */
        private final String key;

        /**
         * Instantiates a new end users storage keys.
         * 
         * @param realKey
         *            the real key
         * @since 2/09/2014, 09:31:48 PM
         */
        EndUsersStorageKeys(String realKey) {
            key = realKey;
        }

        /**
         * Gets the key.
         * 
         * @return the key
         * @since 2/09/2014, 09:31:48 PM
         */
        @Override
        public final String getKey() {
            return key;
        }
    }

    /**
     * Count.
     * 
     * @return the int
     * @since 2/09/2014, 09:31:48 PM
     */
    @Override
    public int count() {
        return super.getQuantity(entityManager, EndUsers.class);
    }
}