/* * Copyright 2009-2012 by KNURT Systeme (http://www.knurt.de) * * Licensed under the Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://creativecommons.org/licenses/by-nc-sa/3.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 de.knurt.fam.core.persistence.dao.ibatis; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.validator.GenericValidator; import org.springframework.orm.ibatis.SqlMapClientTemplate; import de.knurt.fam.core.aspects.logging.FamLog; import de.knurt.fam.core.aspects.security.auth.FamAuth; import de.knurt.fam.core.model.config.Facility; import de.knurt.fam.core.model.config.Role; import de.knurt.fam.core.model.persist.Address; import de.knurt.fam.core.model.persist.ContactDetail; import de.knurt.fam.core.model.persist.User; import de.knurt.fam.core.model.persist.UserMail; import de.knurt.fam.core.model.persist.document.Job; import de.knurt.fam.core.persistence.dao.FamDaoProxy; import de.knurt.fam.core.persistence.dao.UserDao; import de.knurt.heinzelmann.util.time.TimeFrame; /** * dao for users stored in sql * * @author Daniel Oltmanns * @since 0.20090828 */ public class UserDao4ibatis extends UserDao { /** * construct me and set the object container * * @see Db4oServletContextListener#getObjectContainer4users() */ public UserDao4ibatis() { } /** * delete the given user. * * @param user to delete * @see User#excluded * @throws org.springframework.dao.DataIntegrityViolationException if it is not possible to delete this user */ @Override public synchronized boolean delete(User user) { boolean result = false; try { this.sqlMap().delete("User.delete.usermail", user); this.sqlMap().delete("User.delete.logbookentry", user); this.sqlMap().delete("User.delete.contactdetail", user); this.sqlMap().delete("User.delete.booking", user); this.sqlMap().delete("User.delete.address", user); this.sqlMap().delete("User.delete.user", user); result = FamDaoProxy.facilityDao().updateResponsibility(user, new ArrayList<Facility>()); if (result) { user.setJustBeenDeleted(); setChanged(); notifyObservers(user); } } catch (Exception e) { FamLog.exception(e, 201204231012l); } return result; } /** * return all users stored * * @return all users stored */ @SuppressWarnings("unchecked") @Override public List<User> getAll() { return this.sqlMap().queryForList("User.select.all"); } /** * return all users that equals the example. * * @param example user * @return all users that equals the example */ @SuppressWarnings("unchecked") @Override public List<User> getObjectsLike(User example) { return this.sqlMap().queryForList("User.select.select_like", example); } /** {@inheritDoc} */ @Override protected synchronized boolean internInsert(User entry) { boolean result = false; try { assert entry.isPasswordEncoded() == true; // !!!!! assert entry.getId() != null; this.insertOrUpdateAddresses(entry); this.sqlMap().insert("User.insert", entry); result = true; } catch (Exception e) { FamLog.exception(e, 201205071120l); } return result; } /** {@inheritDoc} */ @Override protected synchronized boolean internUpdate(User entry) { boolean result = false; try { this.insertOrUpdateAddresses(entry); this.sqlMap().update("User.update", entry); result = true; } catch (Exception e) { FamLog.exception(e, 201205071121l); } return result; } /** {@inheritDoc} */ @Override public synchronized boolean insert(UserMail mail) { boolean result = false; try { FamSqlMapClientDaoSupport.sqlMap().insert("UserMail.insert", mail); } catch (Exception e) { FamLog.exception(e, 201205071203l); } return result; } /** {@inheritDoc} */ @Override public synchronized boolean update(UserMail mail) { boolean result = false; try { FamSqlMapClientDaoSupport.sqlMap().update("UserMail.update", mail); } catch (Exception e) { FamLog.exception(e, 201205071204l); } return result; } /** {@inheritDoc} */ @Override protected void setIdToNextId(User user) { User userWithId = (User) FamSqlMapClientDaoSupport.sqlMap().queryForObject("User.select.max_id"); if (userWithId != null && userWithId.getId() != null) { user.setId(userWithId.getId() + 1); } else { if (this.getAll().size() == 0) { // hello first user! user.setId(1); } else { FamLog.error("sql mapping did not work", 201011151242l); } } } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public List<UserMail> getUserMailsThatMustBeSendNow() { return FamSqlMapClientDaoSupport.sqlMap().queryForList("UserMail.select.mustBeSendNow", new Date()); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public List<UserMail> getAllUserMails() { return FamSqlMapClientDaoSupport.sqlMap().queryForList("UserMail.select.all"); } private SqlMapClientTemplate sqlMap() { return FamSqlMapClientDaoSupport.sqlMap(); } /** {@inheritDoc} */ @Override public Address getAddress(Integer id) { return (Address) this.sqlMap().queryForObject("Address.select.id", id); } protected synchronized void insertOrUpdateAddresses(User entry) { if (entry == null) { FamLog.info("try to insert or update a address of a none user", 201011151123l); } else if (entry.getUserId() == null) { FamLog.info("try to insert or update a address without user id", 201011151124l); } else if (entry.getMainAddress() == null) { FamLog.info("try to insert or update a user without an address", 201011151122l); entry.setMainAddress(new Address()); FamLog.info("set a new empty address on: " + entry, 201011211055l); this.insertOrUpdateAddresses(entry); } else { Map<String, Object> hashMap = new HashMap<String, Object>(); boolean insert = true; // assert insert; if (entry.getMainAddress().getId() != null) { insert = false; // update hashMap.put("id", entry.getMainAddress().getId()); } hashMap.put("userId", entry.getId()); hashMap.put("zipcode", entry.getMainAddress().getZipcode()); hashMap.put("street", entry.getMainAddress().getStreet()); hashMap.put("streetno", entry.getMainAddress().getStreetno()); hashMap.put("city", entry.getMainAddress().getCity()); hashMap.put("country", entry.getMainAddress().getCountry()); if (insert) { this.sqlMap().insert("Address.insert", hashMap); } else { // update this.sqlMap().update("Address.update", hashMap); } entry.setMainAddressWithId(Integer.parseInt(hashMap.get("id") + "")); } } /** {@inheritDoc} */ @Override public synchronized boolean insert(ContactDetail contactDetail) { boolean result = false; setChanged(); notifyObservers(contactDetail); try { FamSqlMapClientDaoSupport.sqlMap().insert("ContactDetail.insert", contactDetail); } catch (Exception e) { FamLog.exception(e, 201205071200l); } return result; } /** {@inheritDoc} */ @Override public synchronized boolean update(ContactDetail contactDetail) { boolean result = false; setChanged(); notifyObservers(contactDetail); try { FamSqlMapClientDaoSupport.sqlMap().update("ContactDetail.update", contactDetail); } catch (Exception e) { FamLog.exception(e, 201205071201l); } return result; } /** {@inheritDoc} */ @Override public synchronized boolean delete(ContactDetail contactDetail) { boolean result = false; setChanged(); notifyObservers(contactDetail); try { FamSqlMapClientDaoSupport.sqlMap().delete("ContactDetail.delete", contactDetail); result = true; } catch (Exception e) { FamLog.exception(e, 201205071202l); } return result; } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public List<ContactDetail> getAllLike(ContactDetail example) { return FamSqlMapClientDaoSupport.sqlMap().queryForList("ContactDetail.select_like", example); } @SuppressWarnings("unchecked") private List<User> getWhere(String where) { return this.sqlMap().queryForList("User.select.where", where); } /** {@inheritDoc} */ @Override public List<User> getUsersAccountExpired(Date day) { String where = String.format("account_expires = '%s'", Util4Daos4ibatis.SDF_4_DATE.format(day)); return this.getWhere(where); } /** {@inheritDoc} */ @Override public List<User> getUserAccountExpiresIn(TimeFrame timeframe) { String where = String.format("account_expires >= '%s' AND account_expires <= '%s'", Util4Daos4ibatis.SDF_4_DATE.format(timeframe.getDateStart()), Util4Daos4ibatis.SDF_4_DATE.format(timeframe.getDateEnd())); return this.getWhere(where); } /** {@inheritDoc} */ @Override public List<User> getUsersRegistrationIsIn(TimeFrame timeframe) { String biggerEqual = Util4Daos4ibatis.SDF_4_TIMESTAMP.format(timeframe.getDateStart()); String smallerEqual = Util4Daos4ibatis.SDF_4_TIMESTAMP.format(timeframe.getDateEnd()); String where = String.format("registration >= '%s' AND registration <= '%s'", biggerEqual, smallerEqual); return this.getWhere(where); } /** {@inheritDoc} */ @Override public List<User> getUsersWithEMail(String email) throws InvalidParameterException { if (GenericValidator.isEmail(email)) { String where = String.format("mail = \"%s\"", email); return this.getWhere(where); } else { throw new InvalidParameterException(email + " is not an email"); } } /** {@inheritDoc} */ @Override public List<User> getUsersWithRealName(String firstname, String sirname) throws InvalidParameterException { String regexp = "^[^=><'\"]+$"; if (GenericValidator.matchRegexp(firstname, regexp) && GenericValidator.matchRegexp(sirname, regexp)) { String where = String.format("fname = \"%s\" AND sname = \"%s\"", firstname, sirname); return this.getWhere(where); } else { throw new InvalidParameterException(firstname + "; " + sirname + " is not a real name"); } } /** {@inheritDoc} */ @Override public boolean anonymize(User user, User auth) { boolean result = false; if (FamAuth.hasRight(auth, FamAuth.ANONYMIZE_USER, null)) { try { List<Job> jobs = FamDaoProxy.jobsDao().getJobs(user, false); this.sqlMap().delete("User.delete.usermail", user); this.sqlMap().delete("User.delete.contactdetail", user); String oldUsername = user.getUsername(); user.setUsername("anonym"); user.setUniqueUsernameForInsertion(); user.setMail(String.format("%s@anonym.de", user.getUsername())); boolean tmp = false; result = true; for (Job job : jobs) { job.setUsername(user.getUsername()); tmp = job.insertOrUpdate(); if (!tmp) result = false; } if (result) { result = false; Map<String, String> adapterMap = new HashMap<String, String>(); adapterMap.put("old_username", oldUsername); adapterMap.put("new_username", user.getUsername()); this.sqlMap().delete("User.anonymize.logbookentry", adapterMap); this.sqlMap().delete("User.anonymize.booking", adapterMap); this.sqlMap().delete("User.anonymize.address", user); this.sqlMap().delete("User.anonymize.user", user); result = true; user.setAnonymizedName(oldUsername); setChanged(); notifyObservers(user); } } catch (Exception e) { FamLog.exception(e, 201205071050l); } } return result; } /** * {@inheritDoc} username must be only lower case with numbers. */ @Override public User getUserFromUsername(String username) { User result = null; if (!GenericValidator.isBlankOrNull(username)) { username = username.trim(); String regexp = "^[a-z0-9]+$"; if (GenericValidator.matchRegexp(username, regexp)) { List<User> users = this.getWhere(String.format("username = '%s'", username)); if (users != null && users.size() == 1) { result = users.get(0); } else if (users.size() > 1) { FamLog.error(String.format("found %s users with username %s", users.size(), username), 201205091021l); } else { FamLog.info("no user found with username " + username, 201205091338l); } } } return result; } /** {@inheritDoc} */ @Override public List<User> getResponsibleUsers(Facility facility) { String where = String.format("username IN (SELECT username FROM facility_responsibility WHERE facility_key = \"%s\")", facility.getKey()); return this.getWhere(where); } /** {@inheritDoc} */ @Override public List<User> getUserWithRole(Role role) { String where = String.format("roleid = \"%s\"", role.getKey()); return this.getWhere(where); } }