/* * #%L * BroadleafCommerce Profile * %% * Copyright (C) 2009 - 2013 Broadleaf Commerce * %% * 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. * #L% */ package org.broadleafcommerce.profile.core.domain; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.broadleafcommerce.common.admin.domain.AdminMainEntity; import org.broadleafcommerce.common.audit.Auditable; import org.broadleafcommerce.common.audit.AuditableListener; import org.broadleafcommerce.common.copy.CreateResponse; import org.broadleafcommerce.common.copy.MultiTenantCopyContext; import org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyTransform; import org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyTransformMember; import org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyTransformTypes; import org.broadleafcommerce.common.locale.domain.Locale; import org.broadleafcommerce.common.locale.domain.LocaleImpl; import org.broadleafcommerce.common.persistence.PreviewStatus; import org.broadleafcommerce.common.persistence.Previewable; import org.broadleafcommerce.common.presentation.AdminPresentation; import org.broadleafcommerce.common.presentation.AdminPresentationClass; import org.broadleafcommerce.common.presentation.AdminPresentationCollection; import org.broadleafcommerce.common.presentation.AdminPresentationMap; import org.broadleafcommerce.common.presentation.PopulateToOneFieldsEnum; import org.broadleafcommerce.common.presentation.client.AddMethodType; import org.broadleafcommerce.common.presentation.client.VisibilityEnum; import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.Index; import org.hibernate.annotations.Where; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.EntityListeners; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.MapKey; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; @Entity @EntityListeners(value = { AuditableListener.class, CustomerPersistedEntityListener.class }) @Inheritance(strategy = InheritanceType.JOINED) @Table(name = "BLC_CUSTOMER") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "blCustomerElements") @AdminPresentationClass(populateToOneFields = PopulateToOneFieldsEnum.TRUE, friendlyName = "CustomerImpl_baseCustomer") @DirectCopyTransform({ @DirectCopyTransformMember(templateTokens = DirectCopyTransformTypes.PREVIEW, skipOverlaps = true), @DirectCopyTransformMember(templateTokens = DirectCopyTransformTypes.MULTITENANT_SITE) }) public class CustomerImpl implements Customer, AdminMainEntity, Previewable { private static final long serialVersionUID = 1L; @Id @Column(name = "CUSTOMER_ID") @AdminPresentation(friendlyName = "CustomerImpl_Customer_Id", group = "CustomerImpl_Primary_Key", visibility = VisibilityEnum.HIDDEN_ALL) protected Long id; @Embedded protected Auditable auditable = new Auditable(); @Embedded protected PreviewStatus previewable = new PreviewStatus(); @Column(name = "USER_NAME") @AdminPresentation(friendlyName = "CustomerImpl_UserName", order = 4000, group = "CustomerImpl_Customer") protected String username; @Column(name = "PASSWORD") @AdminPresentation(excluded = true) protected String password; @Column(name = "EMAIL_ADDRESS") @Index(name = "CUSTOMER_EMAIL_INDEX", columnNames = { "EMAIL_ADDRESS" }) @AdminPresentation(friendlyName = "CustomerImpl_Email_Address", order = 1000, group = "CustomerImpl_Customer", prominent = true, gridOrder = 1000) protected String emailAddress; @Column(name = "FIRST_NAME") @AdminPresentation(friendlyName = "CustomerImpl_First_Name", order = 2000, group = "CustomerImpl_Customer", prominent = true, gridOrder = 2000) protected String firstName; @Column(name = "LAST_NAME") @AdminPresentation(friendlyName = "CustomerImpl_Last_Name", order = 3000, group = "CustomerImpl_Customer", prominent = true, gridOrder = 3000) protected String lastName; @ManyToOne(targetEntity = ChallengeQuestionImpl.class) @JoinColumn(name = "CHALLENGE_QUESTION_ID") @Index(name = "CUSTOMER_CHALLENGE_INDEX", columnNames = { "CHALLENGE_QUESTION_ID" }) @AdminPresentation(friendlyName = "CustomerImpl_Challenge_Question", order = 4000, tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced, excluded = true) protected ChallengeQuestion challengeQuestion; @Column(name = "CHALLENGE_ANSWER") @AdminPresentation(friendlyName = "CustomerImpl_Challenge_Answer", order = 5000, tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced, excluded = true) protected String challengeAnswer; @Column(name = "PASSWORD_CHANGE_REQUIRED") @AdminPresentation(excluded = true) protected Boolean passwordChangeRequired = false; @Column(name = "RECEIVE_EMAIL") @AdminPresentation(friendlyName = "CustomerImpl_Customer_Receive_Email", order = 1000, tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced) protected Boolean receiveEmail = true; @Column(name = "IS_REGISTERED") @AdminPresentation(friendlyName = "CustomerImpl_Customer_Registered", order = 4000, prominent = true, gridOrder = 4000) protected Boolean registered = false; @Column(name = "DEACTIVATED") @AdminPresentation(friendlyName = "CustomerImpl_Customer_Deactivated", order = 3000, tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced) protected Boolean deactivated = false; @ManyToOne(targetEntity = LocaleImpl.class) @JoinColumn(name = "LOCALE_CODE") @AdminPresentation(friendlyName = "CustomerImpl_Customer_Locale", order = 4000, tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced, excluded = true, visibility = VisibilityEnum.GRID_HIDDEN) protected Locale customerLocale; @OneToMany(mappedBy = "customer", targetEntity = CustomerAttributeImpl.class, cascade = { CascadeType.ALL }, orphanRemoval = true) @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "blStandardElements") @MapKey(name = "name") @BatchSize(size = 50) @AdminPresentationMap(friendlyName = "CustomerAttributeImpl_Attribute_Name", deleteEntityUponRemove = true, forceFreeFormKeys = true, keyPropertyFriendlyName = "ProductAttributeImpl_Attribute_Name", tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced) protected Map<String, CustomerAttribute> customerAttributes = new HashMap<String, CustomerAttribute>(); @OneToMany(mappedBy = "customer", targetEntity = CustomerAddressImpl.class, cascade = { CascadeType.ALL }) @Cascade(value = { org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blStandardElements") @Where(clause = "archived != 'Y'") @AdminPresentationCollection(friendlyName = "CustomerImpl_Customer_Addresses", order = 1000, addType = AddMethodType.PERSIST, tab = Presentation.Tab.Name.Contact, tabOrder = Presentation.Tab.Order.Contact) protected List<CustomerAddress> customerAddresses = new ArrayList<CustomerAddress>(); @OneToMany(mappedBy = "customer", targetEntity = CustomerPhoneImpl.class, cascade = { CascadeType.ALL }) @Cascade(value = { org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blStandardElements") @AdminPresentationCollection(friendlyName = "CustomerImpl_Customer_Phones", order = 2000, addType = AddMethodType.PERSIST, tab = Presentation.Tab.Name.Contact, tabOrder = Presentation.Tab.Order.Contact) protected List<CustomerPhone> customerPhones = new ArrayList<CustomerPhone>(); @OneToMany(mappedBy = "customer", targetEntity = CustomerPaymentImpl.class, cascade = { CascadeType.ALL }) @Cascade(value = { org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blStandardElements") @BatchSize(size = 50) @AdminPresentationCollection(friendlyName = "CustomerImpl_Customer_Payments", order = 3000, addType = AddMethodType.PERSIST, readOnly = true, tab = Presentation.Tab.Name.Contact, tabOrder = Presentation.Tab.Order.Contact) protected List<CustomerPayment> customerPayments = new ArrayList<CustomerPayment>(); @Column(name = "TAX_EXEMPTION_CODE") @AdminPresentation(friendlyName = "CustomerImpl_Customer_TaxExemptCode", order = 5000, tab = Presentation.Tab.Name.Advanced, tabOrder = Presentation.Tab.Order.Advanced, visibility = VisibilityEnum.GRID_HIDDEN) protected String taxExemptionCode; @Transient protected String unencodedPassword; @Transient protected String unencodedChallengeAnswer; @Transient protected boolean anonymous; @Transient protected boolean cookied; @Transient protected boolean loggedIn; @Transient protected Map<String, Object> transientProperties = new HashMap<String, Object>(); @Override public Long getId() { return id; } @Override public void setId(Long id) { this.id = id; } @Override public String getUsername() { return username; } @Override public void setUsername(String username) { this.username = username; } @Override public String getPassword() { return password; } @Override public void setPassword(String password) { this.password = password; } @Override public boolean isPasswordChangeRequired() { return BooleanUtils.toBoolean(passwordChangeRequired); } @Override public void setPasswordChangeRequired(boolean passwordChangeRequired) { this.passwordChangeRequired = Boolean.valueOf(passwordChangeRequired); } @Override public String getFirstName() { return firstName; } @Override public void setFirstName(String firstName) { this.firstName = firstName; } @Override public String getLastName() { return lastName; } @Override public void setLastName(String lastName) { this.lastName = lastName; } @Override public String getEmailAddress() { return emailAddress; } @Override public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } @Override public ChallengeQuestion getChallengeQuestion() { return challengeQuestion; } @Override public void setChallengeQuestion(ChallengeQuestion challengeQuestion) { this.challengeQuestion = challengeQuestion; } @Override public String getChallengeAnswer() { return challengeAnswer; } @Override public void setChallengeAnswer(String challengeAnswer) { this.challengeAnswer = challengeAnswer; } @Override public String getUnencodedPassword() { return unencodedPassword; } @Override public void setUnencodedPassword(String unencodedPassword) { this.unencodedPassword = unencodedPassword; } @Override public boolean isReceiveEmail() { return BooleanUtils.toBoolean(receiveEmail); } @Override public void setReceiveEmail(boolean receiveEmail) { this.receiveEmail = Boolean.valueOf(receiveEmail); } @Override public boolean isRegistered() { return BooleanUtils.toBoolean(registered); } @Override public void setRegistered(boolean registered) { this.registered = Boolean.valueOf(registered); } @Override public String getUnencodedChallengeAnswer() { return unencodedChallengeAnswer; } @Override public void setUnencodedChallengeAnswer(String unencodedChallengeAnswer) { this.unencodedChallengeAnswer = unencodedChallengeAnswer; } @Override public Auditable getAuditable() { return auditable; } @Override public void setAuditable(Auditable auditable) { this.auditable = auditable; } @Override public boolean isAnonymous() { return anonymous; } @Override public boolean isCookied() { return cookied; } @Override public boolean isLoggedIn() { return loggedIn; } @Override public void setAnonymous(boolean anonymous) { this.anonymous = anonymous; if (anonymous) { cookied = false; loggedIn = false; } } @Override public void setCookied(boolean cookied) { this.cookied = cookied; if (cookied) { anonymous = false; loggedIn = false; } } @Override public void setLoggedIn(boolean loggedIn) { this.loggedIn = loggedIn; if (loggedIn) { anonymous = false; cookied = false; } } @Override public Locale getCustomerLocale() { return customerLocale; } @Override public void setCustomerLocale(Locale customerLocale) { this.customerLocale = customerLocale; } @Override public Map<String, CustomerAttribute> getCustomerAttributes() { return customerAttributes; } @Override public void setCustomerAttributes(Map<String, CustomerAttribute> customerAttributes) { this.customerAttributes = customerAttributes; } @Override public boolean isDeactivated() { return BooleanUtils.toBoolean(deactivated); } @Override public void setDeactivated(boolean deactivated) { this.deactivated = Boolean.valueOf(deactivated); } @Override public List<CustomerAddress> getCustomerAddresses() { return customerAddresses; } @Override public void setCustomerAddresses(List<CustomerAddress> customerAddresses) { this.customerAddresses = customerAddresses; } @Override public List<CustomerPhone> getCustomerPhones() { return customerPhones; } @Override public void setCustomerPhones(List<CustomerPhone> customerPhones) { this.customerPhones = customerPhones; } @Override public List<CustomerPayment> getCustomerPayments() { return customerPayments; } @Override public void setCustomerPayments(List<CustomerPayment> customerPayments) { this.customerPayments = customerPayments; } @Override public String getMainEntityName() { if (!StringUtils.isEmpty(getFirstName()) && !StringUtils.isEmpty(getLastName())) { return getFirstName() + " " + getLastName(); } return String.valueOf(getId()); } @Override public Boolean getPreview() { if (previewable == null) { previewable = new PreviewStatus(); } return previewable.getPreview(); } @Override public void setPreview(Boolean preview) { if (previewable == null) { previewable = new PreviewStatus(); } previewable.setPreview(preview); } @Override public Map<String, Object> getTransientProperties() { return transientProperties; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!getClass().isAssignableFrom(obj.getClass())) { return false; } CustomerImpl other = (CustomerImpl) obj; if (id != null && other.id != null) { return id.equals(other.id); } if (username == null) { if (other.username != null) { return false; } } else if (!username.equals(other.username)) { return false; } return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @Override public <G extends Customer> CreateResponse<G> createOrRetrieveCopyInstance(MultiTenantCopyContext context) throws CloneNotSupportedException { CreateResponse<G> createResponse = context.createOrRetrieveCopyInstance(this); if (createResponse.isAlreadyPopulated()) { return createResponse; } Customer cloned = createResponse.getClone(); cloned.setAnonymous(anonymous); cloned.setChallengeAnswer(challengeAnswer); cloned.setChallengeQuestion(challengeQuestion); cloned.setCookied(cookied); for (CustomerAddress entry : customerAddresses) { CustomerAddress clonedEntry = entry.createOrRetrieveCopyInstance(context).getClone(); clonedEntry.setCustomer(cloned); cloned.getCustomerAddresses().add(clonedEntry); } for (Map.Entry<String, CustomerAttribute> entry : customerAttributes.entrySet()) { CustomerAttribute clonedEntry = entry.getValue().createOrRetrieveCopyInstance(context).getClone(); clonedEntry.setCustomer(cloned); cloned.getCustomerAttributes().put(entry.getKey(), clonedEntry); } cloned.setLoggedIn(loggedIn); cloned.setUsername(username); cloned.setUnencodedPassword(unencodedPassword); cloned.setTaxExemptionCode(taxExemptionCode); cloned.setUnencodedChallengeAnswer(unencodedChallengeAnswer); cloned.setRegistered(registered); cloned.setReceiveEmail(receiveEmail); cloned.setPasswordChangeRequired(passwordChangeRequired); cloned.setPassword(password); cloned.setLastName(lastName); cloned.setFirstName(firstName); cloned.setEmailAddress(emailAddress); cloned.setDeactivated(deactivated); for (CustomerPayment entry : customerPayments) { CustomerPayment clonedEntry = entry.createOrRetrieveCopyInstance(context).getClone(); clonedEntry.setCustomer(cloned); cloned.getCustomerPayments().add(clonedEntry); } for (CustomerPhone entry : customerPhones) { CustomerPhone clonedEntry = entry.createOrRetrieveCopyInstance(context).getClone(); clonedEntry.setCustomer(cloned); cloned.getCustomerPhones().add(clonedEntry); } return createResponse; } public static class Presentation { public static class Tab { public static class Name { public static final String Contact = "CustomerImpl_Contact_Tab"; public static final String Advanced = "CustomerImpl_Advanced_Tab"; } public static class Order { public static final int Contact = 2000; public static final int Advanced = 3000; } } } @Override public String getTaxExemptionCode() { return this.taxExemptionCode; } @Override public void setTaxExemptionCode(String exemption) { this.taxExemptionCode = exemption; } @Override public boolean isTaxExempt() { return StringUtils.isNotEmpty(taxExemptionCode); } }