Package org.projectforge.address

Source Code of org.projectforge.address.AddressDao

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition 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; version 3 of the License.
//
// This community edition 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, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.address;

import java.io.PrintWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.projectforge.access.AccessType;
import org.projectforge.access.OperationType;
import org.projectforge.common.DateHelper;
import org.projectforge.common.DateHolder;
import org.projectforge.common.NumberHelper;
import org.projectforge.core.BaseDao;
import org.projectforge.core.BaseSearchFilter;
import org.projectforge.core.Configuration;
import org.projectforge.core.ConfigurationParam;
import org.projectforge.core.QueryFilter;
import org.projectforge.task.TaskDO;
import org.projectforge.task.TaskDao;
import org.projectforge.user.PFUserDO;

/**
*
* @author Kai Reinhard (k.reinhard@micromata.de)
*
*/
public class AddressDao extends BaseDao<AddressDO>
{
  private static final DateFormat V_CARD_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(AddressDao.class);

  private Configuration configuration;

  private TaskDao taskDao;

  public void setConfiguration(final Configuration configuration)
  {
    this.configuration = configuration;
  }

  public void setTaskDao(final TaskDao taskDao)
  {
    this.taskDao = taskDao;
  }

  private PersonalAddressDao personalAddressDao;

  public void setPersonalAddressDao(final PersonalAddressDao personalAddressDao)
  {
    this.personalAddressDao = personalAddressDao;
  }

  public PersonalAddressDao getPersonalAddressDao()
  {
    return personalAddressDao;
  }

  public AddressDao()
  {
    super(AddressDO.class);
  }

  /**
   * Addresses will be assigned to a default task.
   */
  public Integer getDefaultTaskId()
  {
    return configuration.getTaskIdValue(ConfigurationParam.DEFAULT_TASK_ID_4_ADDRESSES);
  }

  public List<Locale> getUsedCommunicationLanguages()
  {
    @SuppressWarnings("unchecked")
    final List<Locale> list = getHibernateTemplate()
    .find(
        "select distinct a.communicationLanguage from AddressDO a where deleted=false and a.communicationLanguage is not null order by a.communicationLanguage");
    return list;
  }

  /**
   * Get the newest address entries (by time of creation).
   * @return
   * @see #getNewestMax()
   */
  public List<AddressDO> getNewest(final BaseSearchFilter filter)
  {
    final QueryFilter queryFilter = new QueryFilter();
    queryFilter.addOrder(Order.desc("created"));
    if (filter.getMaxRows() > 0) {
      queryFilter.setMaxResults(filter.getMaxRows());
    }
    return getList(queryFilter);
  }

  @Override
  public List<AddressDO> getList(final BaseSearchFilter filter)
  {
    final AddressFilter myFilter;
    if (filter instanceof AddressFilter) {
      myFilter = (AddressFilter) filter;
    } else {
      myFilter = new AddressFilter(filter);
    }
    final QueryFilter queryFilter = new QueryFilter(myFilter);
    if (StringUtils.isBlank(myFilter.getSearchString()) == true) {
      if (myFilter.isDeleted() == false) {
        if (myFilter.isNewest() == true) {
          return getNewest(myFilter);
        }
        if (myFilter.isMyFavorites() == true) {
          // Show only favorites.
          return personalAddressDao.getMyAddresses();
        }
      }
    } else {
      if (StringUtils.isNumeric(filter.getSearchString()) == true) {
        myFilter.setSearchString("*" + myFilter.getSearchString() + "*");
      }
    }
    if (myFilter.isFilter() == true) {
      // Proceed contact status:
      // Use filter only for non deleted entries:
      if (myFilter.isActive() == true
          || myFilter.isNonActive() == true
          || myFilter.isUninteresting() == true
          || myFilter.isDeparted() == true
          || myFilter.isPersonaIngrata() == true) {
        final Collection<ContactStatus> col = new ArrayList<ContactStatus>();
        if (myFilter.isActive() == true) {
          col.add(ContactStatus.ACTIVE);
        }
        if (myFilter.isNonActive() == true) {
          col.add(ContactStatus.NON_ACTIVE);
        }
        if (myFilter.isUninteresting() == true) {
          col.add(ContactStatus.UNINTERESTING);
        }
        if (myFilter.isDeparted() == true) {
          col.add(ContactStatus.DEPARTED);
        }
        if (myFilter.isPersonaIngrata() == true) {
          col.add(ContactStatus.PERSONA_INGRATA);
        }
        queryFilter.add(Restrictions.in("contactStatus", col));
      }

      // Proceed address status:
      // Use filter only for non deleted books:
      if (myFilter.isUptodate() == true || myFilter.isOutdated() == true || myFilter.isLeaved() == true) {
        final Collection<AddressStatus> col = new ArrayList<AddressStatus>();
        if (myFilter.isUptodate() == true) {
          col.add(AddressStatus.UPTODATE);
        }
        if (myFilter.isOutdated() == true) {
          col.add(AddressStatus.OUTDATED);
        }
        if (myFilter.isLeaved() == true) {
          col.add(AddressStatus.LEAVED);
        }
        queryFilter.add(Restrictions.in("addressStatus", col));
      }
    }
    queryFilter.addOrder(Order.asc("name"));
    final List<AddressDO> result = getList(queryFilter);
    if (myFilter.isDoublets() == true) {
      final HashSet<String> fullnames = new HashSet<String>();
      final HashSet<String> doubletFullnames = new HashSet<String>();
      for (final AddressDO address : result) {
        final String fullname = getNormalizedFullname(address);
        if (fullnames.contains(fullname) == true) {
          doubletFullnames.add(fullname);
        }
        fullnames.add(fullname);
      }
      final List<AddressDO> doublets = new LinkedList<AddressDO>();
      for (final AddressDO address : result) {
        if (doubletFullnames.contains(getNormalizedFullname(address)) == true) {
          doublets.add(address);
        }
      }
      return doublets;
    }
    return result;
  }

  private String getNormalizedFullname(final AddressDO address)
  {
    final StringBuilder builder = new StringBuilder();
    if (address.getFirstName() != null) {
      builder.append(address.getFirstName().toLowerCase().trim());
    }
    if (address.getName() != null) {
      builder.append(address.getName().toLowerCase().trim());
    }
    return builder.toString();
  }

  /**
   * @param address
   * @param taskId If null, then task will be set to null;
   * @see BaseDao#getOrLoad(Integer)
   */
  public void setTask(final AddressDO address, final Integer taskId)
  {
    final TaskDO task = taskDao.getOrLoad(taskId);
    address.setTask(task);
  }

  /**
   * return Always true, no generic select access needed for address objects.
   * @see org.projectforge.core.BaseDao#hasSelectAccess()
   */
  @Override
  public boolean hasSelectAccess(final PFUserDO user, final boolean throwException)
  {
    return true;
  }

  private void beforeUpdateOrSave(final AddressDO address)
  {
    if (address != null && address.getTaskId() == null) {
      setTask(address, getDefaultTaskId());
    }
  }

  /**
   * @see org.projectforge.core.BaseDao#hasAccess(Object, OperationType)
   */
  @Override
  public boolean hasAccess(final PFUserDO user, final AddressDO obj, final AddressDO oldObj, final OperationType operationType,
      final boolean throwException)
  {
    beforeUpdateOrSave(obj);
    return accessChecker.hasPermission(user, obj.getTaskId(), AccessType.TASKS, operationType, throwException);
  }

  /**
   * @see org.projectforge.core.BaseDao#hasUpdateAccess(Object, Object)
   */
  @Override
  public boolean hasUpdateAccess(final PFUserDO user, final AddressDO obj, final AddressDO dbObj, final boolean throwException)
  {
    Validate.notNull(dbObj);
    Validate.notNull(obj);
    beforeUpdateOrSave(obj);
    Validate.notNull(dbObj.getTaskId());
    Validate.notNull(obj.getTaskId());
    if (accessChecker.hasPermission(user, obj.getTaskId(), AccessType.TASKS, OperationType.UPDATE, throwException) == false) {
      return false;
    }
    if (dbObj.getTaskId().equals(obj.getTaskId()) == false) {
      // User moves the object to another task:
      if (accessChecker.hasPermission(user, obj.getTaskId(), AccessType.TASKS, OperationType.INSERT, throwException) == false) {
        // Inserting of object under new task not allowed.
        return false;
      }
      if (accessChecker.hasPermission(user, dbObj.getTaskId(), AccessType.TASKS, OperationType.DELETE, throwException) == false) {
        // Deleting of object under old task not allowed.
        return false;
      }
    }
    return true;
  }

  /**
   * Get the birthdays of address entries.
   * @param fromDate Search for birthdays from given date (ignoring the year).
   * @param toDate Search for birthdays until given date (ignoring the year).
   * @param max Maximum number of result entries.
   * @param all If false, only the birthdays of favorites will be returned.
   * @return The entries are ordered by date of year and name.
   */
  public Set<BirthdayAddress> getBirthdays(final Date fromDate, final Date toDate, final int max, final boolean all)
  {
    final QueryFilter filter = new QueryFilter();
    filter.add(Restrictions.isNotNull("birthday"));
    final List<AddressDO> list = getList(filter);
    // Uses not Collections.sort because every comparison needs Calendar.getDayOfYear().
    final Set<BirthdayAddress> set = new TreeSet<BirthdayAddress>();
    final Set<Integer> favorites = getFavorites();
    final DateHolder from = new DateHolder(fromDate);
    final DateHolder to = new DateHolder(toDate);
    DateHolder dh;
    final int fromMonth = from.getMonth();
    final int fromDayOfMonth = from.getDayOfMonth();
    final int toMonth = to.getMonth();
    final int toDayOfMonth = to.getDayOfMonth();
    for (final AddressDO address : list) {
      if (all == false && favorites.contains(address.getId()) == false) {
        // Address is not a favorite address, so ignore it.
        continue;
      }
      dh = new DateHolder(address.getBirthday());
      final int month = dh.getMonth();
      final int dayOfMonth = dh.getDayOfMonth();
      if (DateHelper.dateOfYearBetween(month, dayOfMonth, fromMonth, fromDayOfMonth, toMonth, toDayOfMonth) == false) {
        continue;
      }
      final BirthdayAddress ba = new BirthdayAddress(address);
      if (favorites.contains(address.getId()) == true) {
        ba.setFavorite(true);
      }
      set.add(ba);
    }
    return set;
  }

  public List<PersonalAddressDO> getFavoriteVCards()
  {
    final List<PersonalAddressDO> list = personalAddressDao.getList();
    final List<PersonalAddressDO> result = new ArrayList<PersonalAddressDO>();
    if (CollectionUtils.isNotEmpty(list) == true) {
      for (final PersonalAddressDO entry : list) {
        if (entry.isFavoriteCard() == true) {
          result.add(entry);
        }
      }
    }
    return result;
  }

  public Set<Integer> getFavorites()
  {
    final List<PersonalAddressDO> list = personalAddressDao.getList();
    final Set<Integer> result = new HashSet<Integer>();
    if (CollectionUtils.isNotEmpty(list) == true) {
      for (final PersonalAddressDO entry : list) {
        if (entry.isFavoriteCard() == true) {
          result.add(entry.getAddressId());
        }
      }
    }
    return result;
  }

  public void exportFavoriteVCards(final Writer out, final List<PersonalAddressDO> favorites)
  {
    log.info("Exporting personal AddressBook.");
    final PrintWriter pw = new PrintWriter(out);
    for (final PersonalAddressDO entry : favorites) {
      if (entry.isFavoriteCard() == false) {
        // Entry is not marks as vCard-Entry.
        continue;
      }
      final AddressDO addressDO = entry.getAddress();
      exportVCard(pw, addressDO);
    }
    pw.flush();
  }

  /**
   * Exports a single vcard for the given addressDO
   * @param pw
   * @param addressDO
   * @return
   */
  public void exportVCard(final PrintWriter pw, final AddressDO addressDO)
  {
    if (log.isDebugEnabled() == true) {
      log.debug("Exporting vCard for addressDo : " + addressDO != null ? addressDO.getId() : null);
    }
    pw.println("BEGIN:VCARD");
    pw.println("VERSION:3.0");
    pw.print("N:");
    out(pw, addressDO.getName());
    pw.print(';');
    out(pw, addressDO.getFirstName());
    pw.print(";;");
    out(pw, addressDO.getTitle());
    pw.println(";");
    print(pw, "FN:", getFullName(addressDO));
    if (isGiven(addressDO.getOrganization()) == true || isGiven(addressDO.getDivision()) == true) {
      pw.print("ORG:");
      out(pw, addressDO.getOrganization());
      pw.print(';');
      if (isGiven(addressDO.getDivision()) == true) {
        out(pw, addressDO.getDivision());
      }
      pw.println();
    }
    print(pw, "TITLE:", addressDO.getPositionText());
    print(pw, "EMAIL;type=INTERNET;type=WORK;type=pref:", addressDO.getEmail());
    print(pw, "EMAIL;type=INTERNET;type=HOME;type=pref:", addressDO.getPrivateEmail());
    print(pw, "TEL;type=WORK;type=pref:", addressDO.getBusinessPhone());
    print(pw, "TEL;TYPE=CELL:", addressDO.getMobilePhone());
    print(pw, "TEL;type=WORK;type=FAX:", addressDO.getFax());
    print(pw, "TEL;TYPE=HOME:", addressDO.getPrivatePhone());
    print(pw, "TEL;TYPE=HOME;type=CELL:", addressDO.getPrivateMobilePhone());

    if (isGiven(addressDO.getAddressText()) == true || isGiven(addressDO.getCity()) == true || isGiven(addressDO.getZipCode()) == true) {
      pw.print("ADR;TYPE=WORK:;;");
      out(pw, addressDO.getAddressText());
      pw.print(';');
      out(pw, addressDO.getCity());
      pw.print(";;");
      out(pw, addressDO.getZipCode());
      pw.print(';');
      out(pw, addressDO.getCountry());
      pw.println();
    }
    if (isGiven(addressDO.getPrivateAddressText()) == true
        || isGiven(addressDO.getPrivateCity()) == true
        || isGiven(addressDO.getPrivateZipCode()) == true) {
      pw.print("ADR;TYPE=HOME:;;");
      out(pw, addressDO.getPrivateAddressText());
      pw.print(';');
      out(pw, addressDO.getPrivateCity());
      pw.print(";;");
      out(pw, addressDO.getPrivateZipCode());
      pw.print(";");
      pw.println();
    }
    print(pw, "URL;type=pref:", addressDO.getWebsite());
    if (addressDO.getBirthday() != null) {
      print(pw, "BDAY;value=date:", V_CARD_DATE_FORMAT.format(addressDO.getBirthday()));
    }
    if (isGiven(addressDO.getComment()) == true) {
      print(pw, "NOTE:", addressDO.getComment() + "\\nCLASS: WORK");
    } else {
      print(pw, "NOTE:", "CLASS: WORK");
    }
    // pw.println("TZ:+00:00");
    pw.println("CATEGORIES:ProjectForge");
    pw.print("UID:U");
    pw.println(addressDO.getId());
    pw.println("END:VCARD");
    pw.println();
    // Unused: addressDO.getState();
  }

  /**
   * Used by vCard export for field 'FN' (full name). Concatenates first name, last name and title.
   * @return
   */
  public String getFullName(final AddressDO a)
  {
    final StringBuffer buf = new StringBuffer();
    boolean space = false;
    if (isGiven(a.getName()) == true) {
      buf.append(a.getName());
      space = true;
    }
    if (isGiven(a.getFirstName()) == true) {
      if (space == true) {
        buf.append(' ');
      } else {
        space = true;
      }
      buf.append(a.getFirstName());
    }
    if (isGiven(a.getTitle()) == true) {
      if (space == true) {
        buf.append(' ');
      } else {
        space = true;
      }
      buf.append(a.getTitle());
    }
    return buf.toString();
  }

  public List<PersonalAddressDO> getFavoritePhoneEntries()
  {
    final List<PersonalAddressDO> list = personalAddressDao.getList();
    final List<PersonalAddressDO> result = new ArrayList<PersonalAddressDO>();
    if (CollectionUtils.isNotEmpty(list) == true) {
      for (final PersonalAddressDO entry : list) {
        if (entry.isFavoriteBusinessPhone() == true
            || entry.isFavoriteFax() == true
            || entry.isFavoriteMobilePhone() == true
            || entry.isFavoritePrivatePhone() == true) {
          result.add(entry);
        }
      }
    }
    return result;
  }

  /**
   * Throws UserException, if for example the phone list is empty.
   */
  public void exportFavoritePhoneList(final Writer out, final List<PersonalAddressDO> favorites)
  {
    log.info("Exporting phone list");
    final PrintWriter pw = new PrintWriter(out);
    pw.println("\"Name\",\"Phone number\"");
    for (final PersonalAddressDO entry : favorites) {
      final AddressDO address = entry.getAddress();
      String number = address.getBusinessPhone();
      if (entry.isFavoriteBusinessPhone() == true && StringUtils.isNotBlank(number)) {
        appendPhoneEntry(pw, address, "", number);
      }
      number = address.getFax();
      if (entry.isFavoriteFax() == true && StringUtils.isNotBlank(number)) {
        appendPhoneEntry(pw, address, "fax", number);
      }
      number = address.getMobilePhone();
      if (entry.isFavoriteMobilePhone() == true && StringUtils.isNotBlank(number)) {
        appendPhoneEntry(pw, address, "mobil", number);
      }
      number = address.getPrivateMobilePhone();
      if (entry.isFavoritePrivateMobilePhone() == true && StringUtils.isNotBlank(number)) {
        final String str = StringUtils.isNotBlank(address.getMobilePhone()) == true ? "mobil privat" : "mobil";
        appendPhoneEntry(pw, address, str, number);
      }
      number = address.getPrivatePhone();
      if (entry.isFavoritePrivatePhone() == true && StringUtils.isNotBlank(number)) {
        appendPhoneEntry(pw, address, "privat", number);
      }
    }
    pw.flush();
  }

  private void print(final PrintWriter pw, final String key, final String value)
  {
    if (isGiven(value) == false) {
      return;
    }
    pw.print(key);
    out(pw, value);
    pw.println();
  }

  /**
   * Simply calls StringUtils.defaultString(String) and replaces: "\r" -> "", "\n" -> "\\n", "," -> "\\,", ":" -> "\\:" and print the
   * resulted string into given PrintWriter (without newline).
   * @param str
   * @see StringUtils#defaultString(String)
   */
  private void out(final PrintWriter pw, final String str)
  {
    final String s = StringUtils.defaultString(str);
    boolean cr = false;
    for (int i = 0; i < s.length(); i++) {
      final char ch = s.charAt(i);
      if (ch == ':') {
        pw.print("\\:");
      } else if (ch == ',') {
        pw.print("\\,");
      } else if (ch == ';') {
        pw.print("\\;");
      } else if (ch == '\r') {
        pw.print("\\n");
        cr = true;
        continue;
      } else if (ch == '\n') {
        if (cr == false) {
          // Print only \n if not already done by previous \r.
          pw.print("\\n");
        }
      } else {
        pw.print(ch);
      }
      cr = false;
    }
  }

  /**
   * Simply call StringUtils.isNotBlank(String)
   * @param str
   * @return
   * @see StringUtils#isNotBlank(String)
   */
  private boolean isGiven(final String str)
  {
    return StringUtils.isNotBlank(str);
  }

  private void appendPhoneEntry(final PrintWriter pw, final AddressDO address, final String suffix, final String number)
  {
    if (isGiven(number) == false) {
      // Do nothing, number is empty.
      return;
    }
    final String no = NumberHelper
        .extractPhonenumber(number, configuration.getStringValue(ConfigurationParam.DEFAULT_COUNTRY_PHONE_PREFIX));
    final String name = address.getName();
    pw.print("\"");
    if (StringUtils.isNotEmpty(name)) {
      pw.print(name);
    }
    final String firstName = address.getFirstName();
    if (StringUtils.isNotBlank(firstName)) {
      if (StringUtils.isNotBlank(name)) {
        pw.print(", ");
      }
      pw.print(firstName);
    }
    if (StringUtils.isNotEmpty(suffix)) {
      pw.print(' ');
      pw.print(suffix);
    }
    pw.print("\",\"");
    pw.println(no + "\"");
  }

  @Override
  public AddressDO newInstance()
  {
    return new AddressDO();
  }

  /**
   * @see org.projectforge.core.BaseDao#useOwnCriteriaCacheRegion()
   */
  @Override
  protected boolean useOwnCriteriaCacheRegion()
  {
    return true;
  }
}
TOP

Related Classes of org.projectforge.address.AddressDao

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.