/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos 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 Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.dao.customizations; import java.util.HashMap; import java.util.Map; import nl.strohalm.cyclos.dao.BaseDAOImpl; import nl.strohalm.cyclos.entities.Entity; import nl.strohalm.cyclos.entities.Relationship; import nl.strohalm.cyclos.entities.accounts.guarantees.Guarantee; import nl.strohalm.cyclos.entities.accounts.loans.LoanGroup; import nl.strohalm.cyclos.entities.accounts.transactions.Invoice; import nl.strohalm.cyclos.entities.accounts.transactions.Payment; import nl.strohalm.cyclos.entities.accounts.transactions.ScheduledPayment; import nl.strohalm.cyclos.entities.accounts.transactions.Transfer; import nl.strohalm.cyclos.entities.ads.Ad; import nl.strohalm.cyclos.entities.ads.imports.ImportedAd; import nl.strohalm.cyclos.entities.ads.imports.ImportedAdCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.AdCustomField; import nl.strohalm.cyclos.entities.customization.fields.AdCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.AdminCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.CustomField; import nl.strohalm.cyclos.entities.customization.fields.CustomFieldPossibleValue; import nl.strohalm.cyclos.entities.customization.fields.CustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.LoanGroupCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.MemberCustomField; import nl.strohalm.cyclos.entities.customization.fields.MemberCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.MemberRecordCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.OperatorCustomFieldValue; import nl.strohalm.cyclos.entities.customization.fields.PaymentCustomField; import nl.strohalm.cyclos.entities.customization.fields.PaymentCustomFieldValue; import nl.strohalm.cyclos.entities.exceptions.EntityNotFoundException; import nl.strohalm.cyclos.entities.exceptions.UnexpectedEntityException; import nl.strohalm.cyclos.entities.groups.Group; import nl.strohalm.cyclos.entities.members.Administrator; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.entities.members.Operator; import nl.strohalm.cyclos.entities.members.PendingMember; import nl.strohalm.cyclos.entities.members.imports.ImportedMember; import nl.strohalm.cyclos.entities.members.imports.ImportedMemberRecord; import nl.strohalm.cyclos.entities.members.imports.ImportedMemberRecordCustomFieldValue; import nl.strohalm.cyclos.entities.members.records.MemberRecord; import nl.strohalm.cyclos.services.transactions.DoPaymentDTO; import nl.strohalm.cyclos.utils.StringHelper; import org.apache.commons.lang.StringUtils; /** * Implementation class for custom field values * @author rafael */ public class CustomFieldValueDAOImpl extends BaseDAOImpl<CustomFieldValue> implements CustomFieldValueDAO { /** * Represents a meta data entry about a specific custom field nature * @author luis */ private static class MetaEntry { private final String ownerProperty; private final Class<? extends CustomFieldValue> type; public MetaEntry(final String ownerProperty, final Class<? extends CustomFieldValue> type) { this.ownerProperty = ownerProperty; this.type = type; } public String getOwnerProperty() { return ownerProperty; } public Class<? extends CustomFieldValue> getType() { return type; } } public CustomFieldValueDAOImpl() { super(CustomFieldValue.class); } @Override public CustomFieldValue load(final CustomField field, final Object owner, final Relationship... fetch) { final MetaEntry meta = metaEntryFor(owner); final Map<String, Object> params = new HashMap<String, Object>(); params.put("field", field); params.put("owner", owner); final CustomFieldValue fieldValue = uniqueResult("from " + meta.getType().getName() + " v where v.field = :field and v." + meta.getOwnerProperty() + " = :owner", params); if (fieldValue == null) { throw new EntityNotFoundException(meta.getType()); } // If there's a fetch, use the normal load if (fetch != null && fetch.length > 0) { return load(fieldValue.getId(), fetch); } else { return fieldValue; } } @Override public int moveValues(final CustomFieldPossibleValue oldValue, final CustomFieldPossibleValue newValue) { final Map<String, Object> namedParameters = new HashMap<String, Object>(); namedParameters.put("oldValue", oldValue); namedParameters.put("newValue", newValue); return bulkUpdate("update CustomFieldValue v set v.possibleValue = :newValue where v.possibleValue = :oldValue", namedParameters); } @Override public int unHideValues(final MemberCustomField field) { final Map<String, Object> namedParameters = new HashMap<String, Object>(); namedParameters.put("fieldId", field.getId()); StringBuffer hql = new StringBuffer(); hql.append("update MemberCustomFieldValue mv set mv.hidden = false "); hql.append("where mv.field.id = :fieldId"); return bulkUpdate(hql.toString(), namedParameters); } @Override public boolean valueExists(final CustomFieldValue value) { Object owner = value.getOwner(); final MetaEntry meta = metaEntryFor(owner); final Entity ownerEntity = owner instanceof Entity ? (Entity) owner : null; final Map<String, Object> namedParameters = new HashMap<String, Object>(); final CustomField field = getFetchDao().fetch(value.getField()); final StringBuilder hql = new StringBuilder(); hql.append(" select v "); hql.append(" from ").append(meta.getType().getName()).append(" v"); // Specific left joins might be needed if (field instanceof PaymentCustomField) { hql.append(" left join v.transfer t"); hql.append(" left join v.scheduledPayment sp"); } hql.append(" where v.field = :field "); // Check specific field types if (field instanceof MemberCustomField) { // Ignore members in removed group hql.append(" and v.member.group.status <> :removed"); namedParameters.put("removed", Group.Status.REMOVED); } else if (field instanceof AdCustomField) { // Ignore ads which have been removed hql.append(" and v.ad.deleteDate is null"); } else if (field instanceof PaymentCustomField) { // Ignore transfers which were denied or canceled hql.append(" and ((t.id is null) or (t.status not in (:denied, :canceled)))"); hql.append(" and ((sp.id is null) or (sp.status not in (:denied, :canceled)))"); namedParameters.put("denied", Payment.Status.DENIED); namedParameters.put("canceled", Payment.Status.CANCELED); } if (field.getType() == CustomField.Type.ENUMERATED) { hql.append(" and v.possibleValue.value = :value"); } else { hql.append(" and v.stringValue = :value"); } namedParameters.put("field", field); String val = value.getValue(); if (StringUtils.isNotEmpty(field.getPattern())) { val = StringHelper.removeMask(field.getPattern(), val); } namedParameters.put("value", val); final CustomFieldValue existingValue = uniqueResult(hql.toString(), namedParameters); if (ownerEntity == null || ownerEntity.isTransient()) { return existingValue != null; } else { return existingValue != null && !ownerEntity.equals(existingValue.getOwner()); } } private MetaEntry metaEntryFor(final Object owner) { // Determine the type String ownerProperty; Class<? extends CustomFieldValue> type; if (owner instanceof Member) { ownerProperty = "member"; type = MemberCustomFieldValue.class; } else if (owner instanceof PendingMember) { ownerProperty = "pendingMember"; type = MemberCustomFieldValue.class; } else if (owner instanceof ImportedMember) { ownerProperty = "importedMember"; type = MemberCustomFieldValue.class; } else if (owner instanceof Administrator) { ownerProperty = "admin"; type = AdminCustomFieldValue.class; } else if (owner instanceof Operator) { ownerProperty = "operator"; type = OperatorCustomFieldValue.class; } else if (owner instanceof Ad) { ownerProperty = "ad"; type = AdCustomFieldValue.class; } else if (owner instanceof Transfer || owner instanceof DoPaymentDTO) { ownerProperty = "transfer"; type = PaymentCustomFieldValue.class; } else if (owner instanceof ScheduledPayment) { ownerProperty = "scheduledPayment"; type = PaymentCustomFieldValue.class; } else if (owner instanceof Invoice) { ownerProperty = "invoice"; type = PaymentCustomFieldValue.class; } else if (owner instanceof Guarantee) { ownerProperty = "guarantee"; type = PaymentCustomFieldValue.class; } else if (owner instanceof LoanGroup) { ownerProperty = "loanGroup"; type = LoanGroupCustomFieldValue.class; } else if (owner instanceof MemberRecord) { ownerProperty = "memberRecord"; type = MemberRecordCustomFieldValue.class; } else if (owner instanceof ImportedMemberRecord) { ownerProperty = "memberRecord"; type = ImportedMemberRecordCustomFieldValue.class; } else if (owner instanceof ImportedAd) { ownerProperty = "ad"; type = ImportedAdCustomFieldValue.class; } else { throw new UnexpectedEntityException(); } return new MetaEntry(ownerProperty, type); } }