package com.cin.ejb.transactionejb;
import java.rmi.RemoteException;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import com.cin.dto.JobDTO;
import com.cin.dto.SearchDTO;
import com.cin.dto.StatisticsDTO;
import com.cin.dto.UserDTO;
import com.cin.dto.ZipDTO;
import com.cin.entity.Education;
import com.cin.entity.Industry;
import com.cin.entity.Investment;
import com.cin.entity.Job;
import com.cin.entity.Migration;
import com.cin.entity.Occupation;
import com.cin.entity.Userrecord;
import com.cin.entity.Youth;
import com.cin.exceptions.PersistenceException;
import com.cin.exceptions.UserNotFoundException;
import com.cin.jndi.lookup.EJBLookup;
import com.cin.log.EventLogger;
import com.cin.translators.DataTranslator;
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Stateless(name="UserFactoryEJB",mappedName="UserFactoryEJB")
public class UserFactoryEJB implements UserFactoryLocal, UserFactoryRemote{
@javax.persistence.PersistenceContext(unitName = "census_context")
private EntityManager manager;
/**
* This method is to retrieve the User record from
* the database as an entity object along with all
* the other details like job/education/investment details
* of the user.
*/
public UserDTO findUserBySsn(int pSsn) {
Userrecord pEntity = (Userrecord) manager.find(Userrecord.class, pSsn);
if( pEntity == null ){
return null;
} else {
return new UserDTO(pEntity);
}
}
public List<UserDTO> findUsersBySearchCriteria(SearchDTO pDTO) {
String aZipCode = null;
boolean isSet = false;
if( pDTO.getZipCode() > 0 ){
aZipCode = String.valueOf(pDTO.getZipCode());
}
String anEducation = pDTO.getEducation();
if( anEducation != null ){
anEducation = anEducation.trim();
}
String anOccupation = pDTO.getOccupationCategory();
if( anOccupation != null ){
anOccupation = anOccupation.trim();
}
String aMarital = pDTO.getMaritalStatus();
if( aMarital != null ){
aMarital = aMarital.trim();
}
DataTranslator aTranslator = new DataTranslator();
StringBuilder aQuery = new StringBuilder();
aQuery.append("SELECT u ");
aQuery.append("FROM Userrecord u LEFT JOIN u.job j LEFT JOIN j.occupation o LEFT JOIN u.education e ");
if(aZipCode != null && aZipCode.trim().length() > 0) {
aQuery.append(" WHERE ");
aQuery.append("u.zip = '" + aZipCode + "' ");
isSet = true;
}
if (anEducation != null && anEducation.trim().length() > 0) {
if (isSet) {
aQuery.append(" AND ");
} else {
aQuery.append(" WHERE ");
}
aQuery.append(" UPPER(TRIM( e.education )) like '%" + anEducation.toUpperCase() + "%' ");
isSet = true;
}
if(anOccupation != null && anOccupation.trim().length() > 0 ) {
int anOccupationCode = this.findOccupationCode(anOccupation);
if(isSet) {
aQuery.append(" AND " );
} else {
aQuery.append(" WHERE ");
}
aQuery.append(" o.occupationcode = " + anOccupationCode + " ");
isSet = true;
}
if(aMarital != null && aMarital.trim().length() > 0) {
if(isSet) {
aQuery.append(" AND " );
}
else {
aQuery.append(" WHERE ");
}
aQuery.append(" UPPER(TRIM( u.marital )) like '%" + aMarital.toUpperCase() + "%' ");
isSet = true;
}
Query aQueryObject = manager.createQuery(aQuery.toString());
Collection<?> theUserDetails = aQueryObject.getResultList();
return aTranslator.translateToUserDTO(theUserDetails);
}
private int findOccupationCode(String anOccupation) {
try {
Transaction transactionEjb = EJBLookup.getInstance().getTransactionEJB();
Occupation occEntity = transactionEjb.findOccupationCode(anOccupation);
if(occEntity != null) {
return occEntity.getOccupationcode();
}
} catch (RemoteException e) {
throw new EJBException(e);
} catch (NamingException e) {
throw new EJBException(e);
}
return 0;
}
public List<UserDTO> findUsersByCode(int pIndCode,int pOccCode) {
DataTranslator aTranslator = new DataTranslator();
String selectString = "select u from Userrecord u ";
StringBuilder whereString = null;
if(pOccCode > 0) {
whereString = new StringBuilder();
whereString.append("where u.job.occupation.occupationcode = :occupationCode ");
}
if(pIndCode > 0) {
if(whereString == null) {
whereString = new StringBuilder();
whereString.append(" where " );
} else {
whereString.append(" and ");
}
whereString.append("u.job.industry.industrycode = :industryCode ");
}
if( whereString == null ){
return null;
}
Query aQueryObject = manager.createQuery(selectString + whereString.toString());
if( pOccCode > 0){
aQueryObject.setParameter("occupationCode", pOccCode);
}
if( pIndCode > 0){
aQueryObject.setParameter("industryCode", pIndCode);
}
List<?> theUserDetails = aQueryObject.getResultList();
return aTranslator.translateToUserDTO(theUserDetails);
}
public UserDTO addUser(UserDTO user){
Userrecord userEjb = user.toEJB();
if( userEjb.getJob() != null ){
// TODO finish this
JobDTO jobDto = user.getJobDetails();
if( jobDto.getIndustryCode() != 0 ){
//userEjb.getJob().setIndustry(getIndustryByCode());
}
if( jobDto.getOccupationCode() != 0 ){
//userEjb.getJob().setgetOccupation(getgetOccupationByCode());
}
}
persist(userEjb);
return new UserDTO(userEjb);
}
public void deleteUser(UserDTO user){
Userrecord userEjb = (Userrecord) manager.find(Userrecord.class, user.getSsn());
remove(userEjb);
// data from all related tables tables should be deleted automatically by cascade
}
public void updateUserDetail(UserDTO user) throws UserNotFoundException{
Userrecord ejb = manager.find(Userrecord.class, user.getSsn());
if( ejb == null ){
throw new com.cin.exceptions.UserNotFoundException("Cannot find given user.");
}else{
ejb.setAge(user.getAge());
ejb.setBirthcountry(user.getBirthCountry());
ejb.setCitizenship(user.getCitizenship());
ejb.setDetail(user.getDetail());
ejb.setFatherorigin(user.getFatherOrigin());
ejb.setHouseholddetail(user.getHouseholdDetail());
ejb.setMarital(user.getMarital());
ejb.setMotherorigin(user.getMotherOrigin());
ejb.setName(user.getName());
ejb.setRace(user.getRace());
ejb.setSex(user.getSex());
ejb.setTaxstat(user.getTaxStatus());
ejb.setZip(user.getZipCode());
update(ejb);
}
}
public void updateUserEducation(UserDTO user){
Education ejb = manager.find(Education.class, user.getSsn());
if( ejb == null ){
ejb = user.getEducation().toEJB(user.getSsn());
persist(ejb);
} else {
ejb.setEducation(user.getEducation().getEducation());
ejb.setEduenroll(user.getEducation().getEduenroll());
update(ejb);
}
}
public void updateUserJob(UserDTO user)
{
Job ejb = manager.find(Job.class, user.getSsn());
if( ejb == null )
{
ejb = user.getJobDetails().toEJB(user.getSsn());
persist(ejb);
} else {
Industry ind = new Industry();
Occupation occ = new Occupation();
ind.setIndustrycode(user.getJobDetails().getIndustryCode());
occ.setOccupationcode(user.getJobDetails().getOccupationCode());
ejb.setEmployersize(user.getJobDetails().getEmployerSize());
ejb.setIndustry(ind);
ejb.setOccupation(occ);
ejb.setSelfemployed(user.getJobDetails().getSelfEmployed());
ejb.setUnionmember(user.getJobDetails().getUnionMember());
ejb.setWeekwage(user.getJobDetails().getWeekWage());
ejb.setWorkclass(user.getJobDetails().getWorkClass());
ejb.setWorkweeks(user.getJobDetails().getWorkWeeks());
update(ejb);
}
}
public void updateUserMigration(UserDTO user)
{
Migration ejb = manager.find(Migration.class, user.getSsn());
if( ejb == null )
{
ejb = user.getMigration().toEJB(user.getSsn());
persist(ejb);
} else {
ejb.setMigrationcode(user.getMigration().getMigrationCode());
ejb.setMigrationdistance(user.getMigration().getMigrationDistance());
ejb.setMigrationfromsunbelt(user.getMigration().getMigrationFromSunBelt());
ejb.setMigrationmove(user.getMigration().getMigrationMove());
update(ejb);
}
}
public void updateUserInvestment(UserDTO user){
Investment ejb = manager.find(Investment.class, user.getSsn());
if( ejb == null ){
ejb = user.getInvestmentDetails().toEJB(user.getSsn());
persist(ejb);
} else {
ejb.setCapitalgains(user.getInvestmentDetails().getCapitalGains());
ejb.setCapitallosses(user.getInvestmentDetails().getCapitalLosses());
ejb.setStockdividends(user.getInvestmentDetails().getStockDividends());
update(ejb);
}
}
public void updateUserYouth(UserDTO user){
Youth ejb = manager.find(Youth.class, user.getSsn());
if( ejb == null ){
ejb = user.getYouth().toEJB(user.getSsn());
persist(ejb);
} else {
ejb.setParents(user.getYouth().getParents());
}
}
public List<ZipDTO> findZipForState(String pState){
String aQuery = "select o from Ziptable o where o.statename = '" + pState + "' " ;
Query aQueryObject = manager.createQuery(aQuery);
DataTranslator aTranslator = new DataTranslator();
List<?> theZipDetails = aQueryObject.getResultList();
return aTranslator.translateToZipDTO(theZipDetails);
}
public List<UserDTO> findUserForZip(int pZip) {
String aQuery = "select o from Userrecord o where o.zip " ;
if(pZip == 0) {
aQuery = aQuery + " is null";
}
else {
aQuery = aQuery + " = '" + pZip + "'";
}
Query aQueryObject = manager.createQuery(aQuery);
DataTranslator aTranslator = new DataTranslator();
List<?> theUserDetails = aQueryObject.getResultList();
return aTranslator.translateToUserDTO(theUserDetails);
}
public List<UserDTO> findForIncomeStatistics(StatisticsDTO pStatistics) throws PersistenceException {
TransactionRemote aTxnRemote = null;
StringBuilder query = new StringBuilder();
String aState = pStatistics.getState();
String aOccCategory = pStatistics.getOccCategory();
String aIndCategory = pStatistics.getIndCategory();
String aRace = pStatistics.getRace();
String anEducationLevel = pStatistics.getEducationLevel();
int aOccCode = pStatistics.getOccCode();
int aIndCode = pStatistics.getIndustryCode();
String stateAbbv = null;
boolean isSearchCriteria = false;
query.append("SELECT u FROM Userrecord u ");
try {
aTxnRemote = EJBLookup.getInstance().getTransactionEJB();
if(aState != null) {
stateAbbv = aTxnRemote.getStateAbbv(aState);
}
}
catch(RemoteException pException) {
EventLogger.getInstance().log(Level.SEVERE, pException.getMessage());
}
catch(NamingException pException) {
EventLogger.getInstance().log(Level.SEVERE, pException.getMessage());
}
if( stateAbbv != null ){
query.append(" WHERE u.zip = ANY ( SELECT z.zip FROM Ziptable z WHERE UPPER(z.statename) = '"+ stateAbbv + "' ) ");
isSearchCriteria = true;
}
//checking if the occ. code or the occ. category is present implies statistics
//based on occ categ/occ code & ind. categ./ind.code is requested.
else if((aOccCategory != null && !aOccCategory.equals("")) || aOccCode > 0) {
query = new StringBuilder();
if(aOccCategory != null) {
Occupation anEntity = aTxnRemote.findOccupationCode(aOccCategory);
if(anEntity != null) {
aOccCode = anEntity.getOccupationcode();
}
}
if((aIndCategory != null && !aIndCategory.equals("")) || aIndCode > 0) {
if(aIndCategory != null) {
Industry indEntity = aTxnRemote.findIndCode(aIndCategory);
if(indEntity != null)
aIndCode = indEntity.getIndustrycode();
}
}
query.append("SELECT u ");
query.append("FROM Userrecord u, IN( u.job ) j, IN( j.occupation ) o, IN( j.industry ) i ");
query.append(" WHERE i.industrycode = " + aIndCode);
query.append(" AND o.occupationcode = " + aOccCode);
isSearchCriteria = true;
}
else if(aRace != null && !aRace.equals("")) {
query.append(" WHERE upper(trim(u.race)) like '%" + aRace.toUpperCase() + "%'");
isSearchCriteria = true;
}
else if(anEducationLevel != null && !anEducationLevel.equals("")) {
query = new StringBuilder();
query.append("SELECT u ");
query.append("FROM Userrecord u, IN( u.education ) e ");
query.append(" WHERE upper(trim(e.education)) like '%" + anEducationLevel.toUpperCase() + "%'");
isSearchCriteria = true;
}
if(isSearchCriteria) {
Query q = manager.createQuery(query.toString());
List<?> theEntity = q.getResultList();
DataTranslator aTranslator = new DataTranslator();
return aTranslator.translateToUserDTO(theEntity);
}
return null;
}
private void remove(Object obj) {
manager.remove(obj);
}
private void persist(Object obj) {
manager.persist(obj);
manager.refresh(obj);
}
private void update(Object obj) {
manager.merge(obj);
manager.flush();
}
}