merge-update from trunk
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / User.java
index f0f6d07f1dcacd3de7341d6c247c3e3234d7d5c2..2e6ad25107d377bb31ef752a39eaa62e766a7524 100644 (file)
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy\r
+* http://www.e-taxonomy.eu\r
+*\r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+\r
 package eu.etaxonomy.cdm.model.common;\r
 \r
+import java.util.Collection;\r
 import java.util.HashSet;\r
 import java.util.Set;\r
-import java.util.TreeSet;\r
 \r
+import javax.persistence.Column;\r
 import javax.persistence.Entity;\r
 import javax.persistence.FetchType;\r
 import javax.persistence.ManyToMany;\r
+import javax.persistence.OneToOne;\r
+import javax.persistence.Table;\r
 import javax.persistence.Transient;\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlElementWrapper;\r
+import javax.xml.bind.annotation.XmlIDREF;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+import javax.xml.bind.annotation.XmlSchemaType;\r
+import javax.xml.bind.annotation.XmlTransient;\r
+import javax.xml.bind.annotation.XmlType;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.hibernate.annotations.Cascade;\r
+import org.hibernate.annotations.CascadeType;\r
+import org.hibernate.envers.Audited;\r
+import org.hibernate.envers.NotAudited;\r
+import org.hibernate.search.annotations.Analyze;\r
+import org.hibernate.search.annotations.Field;\r
+import org.hibernate.search.annotations.Indexed;\r
+import org.hibernate.search.annotations.IndexedEmbedded;\r
+import org.springframework.security.core.GrantedAuthority;\r
+import org.springframework.security.core.userdetails.UserDetails;\r
 \r
-import org.hibernate.annotations.NaturalId;\r
-import org.springframework.security.GrantedAuthority;\r
-import org.springframework.security.userdetails.UserDetails;\r
+import eu.etaxonomy.cdm.model.agent.Person;\r
 \r
+@XmlAccessorType(XmlAccessType.FIELD)\r
+@XmlType(name = "User", propOrder = {\r
+    "username",\r
+    "password",\r
+    "emailAddress",\r
+    "grantedAuthorities",\r
+    "groups",\r
+    "enabled",\r
+    "accountNonExpired",\r
+    "credentialsNonExpired",\r
+    "accountNonLocked",\r
+    "person"\r
+})\r
+@XmlRootElement(name = "User")\r
 @Entity\r
+@Indexed(index = "eu.etaxonomy.cdm.model.common.User")\r
+@Audited\r
+@Table(name = "UserAccount")\r
 public class User extends CdmBase implements UserDetails {\r
+    private static final long serialVersionUID = 6582191171369439163L;\r
+    private static final Logger logger = Logger.getLogger(User.class);\r
+\r
+ // **************************** FACTORY *****************************************/   \r
+    \r
+    public static User NewInstance(String username, String pwd){\r
+        User user = new User();\r
+        user.setUsername(username);\r
+        user.setPassword(pwd);\r
+\r
+        user.setAccountNonExpired(true);\r
+        user.setAccountNonLocked(true);\r
+        user.setCredentialsNonExpired(true);\r
+        user.setEnabled(true);\r
+\r
+        return user;\r
+    }\r
+\r
+    public static User NewInstance(String personTitle, String username, String pwd){\r
+        User user = new User();\r
+        user.setUsername(username);\r
+        user.setPassword(pwd);\r
+\r
+        user.setAccountNonExpired(true);\r
+        user.setAccountNonLocked(true);\r
+        user.setCredentialsNonExpired(true);\r
+        user.setEnabled(true);\r
+        Person userPerson = Person.NewTitledInstance(personTitle);\r
+        user.setPerson(userPerson);\r
+\r
+        return user;\r
+    }\r
+\r
+//***************************** Fields *********************** /\r
+    \r
+    @XmlElement(name = "Username")\r
+    @Column(unique = true)\r
+    @Field(analyze = Analyze.NO)\r
+    protected String username;\r
+\r
+    /**\r
+     * a salted, MD5 encoded hash of the plaintext password\r
+     */\r
+    @XmlElement(name = "Password")\r
+    @NotAudited\r
+    protected String password;\r
+\r
+    @XmlElement(name = "EmailAddress")\r
+    protected String emailAddress;\r
+\r
+    @XmlElementWrapper(name = "GrantedAuthorities")\r
+    @XmlElement(name = "GrantedAuthority", type = GrantedAuthorityImpl.class)\r
+    @XmlIDREF\r
+    @XmlSchemaType(name = "IDREF")\r
+    @ManyToMany(fetch = FetchType.LAZY, targetEntity = GrantedAuthorityImpl.class)\r
+    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.REFRESH}) // see #2414 (Group updating doesn't work)\r
+    @NotAudited\r
+    protected Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();  //authorities of this user only\r
+\r
+    @XmlElementWrapper(name = "Groups")\r
+    @XmlElement(name = "Group")\r
+    @XmlIDREF\r
+    @XmlSchemaType(name = "IDREF")\r
+    @ManyToMany(fetch = FetchType.LAZY)\r
+    @Cascade(CascadeType.REFRESH) // see #2414 (Group updating doesn't work)\r
+    @IndexedEmbedded(depth = 1)\r
+    @NotAudited\r
+    protected Set<Group> groups = new HashSet<Group>();\r
+\r
+    @XmlElement(name = "Enabled")\r
+    protected boolean enabled;\r
+\r
+    @XmlElement(name = "AccountNonExpired")\r
+    protected boolean accountNonExpired;\r
+\r
+    @XmlElement(name = "CredentialsNonExpired")\r
+    protected boolean credentialsNonExpired;\r
+\r
+    @XmlElement(name = "AccountNonLocked")\r
+    protected boolean accountNonLocked;\r
+\r
+    @XmlElement(name = "Person")\r
+    @XmlIDREF\r
+    @XmlSchemaType(name = "IDREF")\r
+    @OneToOne(fetch = FetchType.LAZY)\r
+    @Cascade({CascadeType.SAVE_UPDATE})\r
+    @IndexedEmbedded(depth = 1)\r
+    protected Person person;\r
+\r
+    @XmlTransient\r
+    @Transient\r
+    private Set<GrantedAuthority> authorities;  //authorities of this user and of all groups the user belongs to\r
+\r
+//***************************** Constructor *********************** /\r
+    \r
+    protected User(){\r
+        super();\r
+    }\r
+    \r
+// ***************************** METHODS ******************************/\r
+    \r
+    /**\r
+     * Initializes or refreshes the collection of authorities, See\r
+     * {@link #getAuthorities()}\r
+     */\r
+    //FIXME made public as preliminary solution to #4053 (Transient field User.authorities not refreshed on reloading entity)\r
+    public void initAuthorities() {\r
+        authorities = new HashSet<GrantedAuthority>();\r
+        authorities.addAll(grantedAuthorities);\r
+        for(Group group : groups) {\r
+            authorities.addAll(group.getGrantedAuthorities());\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Implementation of {@link UserDetails#getAuthorities()}\r
+     *\r
+     * {@inheritDoc}\r
+     *\r
+     * @return returns all {@code Set<GrantedAuthority>} instances contained in\r
+     *         the sets {@link #getGrantedAuthorities()} and\r
+     *         {@link #getGroups()}\r
+     */\r
+    @Override\r
+    @Transient\r
+    public Collection<GrantedAuthority> getAuthorities() {\r
+        if(authorities == null || authorities.size() == 0) {\r
+            initAuthorities();\r
+        }\r
+        return authorities;\r
+    }\r
+\r
+    @Override\r
+    public String getPassword() {\r
+        return password;\r
+    }\r
+\r
+    @Override\r
+    public String getUsername() {\r
+        return username;\r
+    }\r
+\r
+    @Override\r
+    public boolean isAccountNonExpired() {\r
+        return accountNonExpired;\r
+    }\r
+\r
+    @Override\r
+    public boolean isAccountNonLocked() {\r
+        return accountNonLocked;\r
+    }\r
+\r
+    @Override\r
+    public boolean isCredentialsNonExpired() {\r
+        return credentialsNonExpired;\r
+    }\r
+\r
+    @Override\r
+    public boolean isEnabled() {\r
+        return enabled;\r
+    }\r
+\r
+    public String getEmailAddress() {\r
+        return emailAddress;\r
+    }\r
+\r
+    public void setEmailAddress(String emailAddress) {\r
+        this.emailAddress = emailAddress;\r
+    }\r
+\r
+    public Set<GrantedAuthority> getGrantedAuthorities() {\r
+        return grantedAuthorities;\r
+    }\r
+\r
+    public void setGrantedAuthorities(Set<GrantedAuthority> grantedAuthorities) {\r
+        this.grantedAuthorities = grantedAuthorities;\r
+        initAuthorities();\r
+    }\r
+\r
+    public void setUsername(String username) {\r
+        this.username = username;\r
+    }\r
+\r
+    public void setPassword(String password) {\r
+        this.password = password;\r
+    }\r
+\r
+    public void setEnabled(boolean enabled) {\r
+        this.enabled = enabled;\r
+    }\r
+\r
+    public void setAccountNonExpired(boolean accountNonExpired) {\r
+        this.accountNonExpired = accountNonExpired;\r
+    }\r
+\r
+    public void setCredentialsNonExpired(boolean credentialsNonExpired) {\r
+        this.credentialsNonExpired = credentialsNonExpired;\r
+    }\r
+\r
+    public void setAccountNonLocked(boolean accountNonLocked) {\r
+        this.accountNonLocked = accountNonLocked;\r
+    }\r
+\r
+    protected void setGroups(Set<Group> groups) {\r
+        this.groups = groups;\r
+        initAuthorities();\r
+    }\r
+\r
+    public Set<Group> getGroups() {\r
+        return groups;\r
+    }\r
+\r
+\r
+    public Person getPerson() {\r
+        return person;\r
+    }\r
+\r
+    public void setPerson(Person person) {\r
+        this.person = person;\r
+    }\r
+\r
+//*********************** CLONE ********************************************************/\r
+\r
+    /**\r
+     * Clones <i>this</i> User. This is a shortcut that enables to create\r
+     * a new instance that differs only slightly from <i>this</i> User.\r
+     * The corresponding person is cloned.\r
+     *\r
+     * @see eu.etaxonomy.cdm.model.common.CdmBase#clone()\r
+     * @see java.lang.Object#clone()\r
+     */\r
+    @Override\r
+    public Object clone() {\r
+        try{\r
+            User result = (User)super.clone();\r
+            result.setPerson((Person)this.person.clone());\r
+            return result;\r
+        } catch (CloneNotSupportedException e){\r
+            logger.warn("Object does not implement cloneable");\r
+            e.printStackTrace();\r
+            return null;\r
+        }\r
+\r
 \r
-       /**\r
-        * \r
-        */\r
-       private static final long serialVersionUID = 6582191171369439163L;\r
-\r
-       protected String username;\r
-       \r
-       /**\r
-        * a salted, MD5 encoded hash of the plaintext password\r
-        */\r
-       protected String password;\r
-       \r
-       protected String emailAddress;\r
-       \r
-       protected Set <GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();\r
-       \r
-       protected Set<Group> groups = new HashSet<Group>();\r
-       \r
-       protected boolean enabled;\r
-       \r
-       protected boolean accountNonExpired;\r
-       \r
-       protected boolean credentialsNonExpired;\r
-       \r
-       protected boolean accountNonLocked;     \r
-       \r
-       private GrantedAuthority[] authorities;\r
-       \r
-       private void initAuthorities() {\r
-               Set<GrantedAuthority> allAuthorities = new TreeSet<GrantedAuthority>();\r
-               allAuthorities.addAll(grantedAuthorities);\r
-               for(Group group : groups) {\r
-                       allAuthorities.addAll(group.getGrantedAuthorities());\r
-               }\r
-               \r
-               authorities = allAuthorities.toArray(new GrantedAuthority[allAuthorities.size()]);\r
-       }\r
-       \r
-       @Transient\r
-       public GrantedAuthority[] getAuthorities() {\r
-               if(authorities == null) initAuthorities();\r
-               return authorities;\r
-       }\r
-\r
-       public String getPassword() {\r
-               return password;\r
-       }\r
-\r
-       @NaturalId\r
-       public String getUsername() {\r
-               return username;\r
-       }\r
-\r
-       public boolean isAccountNonExpired() {\r
-               return accountNonExpired;\r
-       }\r
-\r
-       public boolean isAccountNonLocked() {\r
-               return accountNonLocked;\r
-       }\r
-\r
-       public boolean isCredentialsNonExpired() {\r
-               return credentialsNonExpired;\r
-       }\r
-\r
-       public boolean isEnabled() {\r
-               return enabled;\r
-       }\r
-\r
-       public String getEmailAddress() {\r
-               return emailAddress;\r
-       }\r
-\r
-       public void setEmailAddress(String emailAddress) {\r
-               this.emailAddress = emailAddress;\r
-       }\r
-\r
-       @ManyToMany(fetch = FetchType.LAZY, targetEntity = GrantedAuthorityImpl.class)\r
-       public Set<GrantedAuthority> getGrantedAuthorities() {\r
-               return grantedAuthorities;\r
-       }\r
-\r
-       public void setGrantedAuthorities(Set<GrantedAuthority> grantedAuthorities) {\r
-               this.grantedAuthorities = grantedAuthorities;\r
-               initAuthorities();\r
-       }\r
-\r
-       public void setUsername(String username) {\r
-               this.username = username;\r
-       }\r
-\r
-       public void setPassword(String password) {\r
-               this.password = password;\r
-       }\r
-\r
-       public void setEnabled(boolean enabled) {\r
-               this.enabled = enabled;\r
-       }\r
-\r
-       public void setAccountNonExpired(boolean accountNonExpired) {\r
-               this.accountNonExpired = accountNonExpired;\r
-       }\r
-\r
-       public void setCredentialsNonExpired(boolean credentialsNonExpired) {\r
-               this.credentialsNonExpired = credentialsNonExpired;\r
-       }\r
-\r
-       public void setAccountNonLocked(boolean accountNonLocked) {\r
-               this.accountNonLocked = accountNonLocked;\r
-       }\r
-       \r
-       protected void setGroups(Set<Group> groups) {\r
-               this.groups = groups;\r
-               initAuthorities();\r
-       }\r
-       \r
-       @ManyToMany(fetch = FetchType.LAZY)\r
-       public Set<Group> getGroups() {\r
-               return groups;\r
-       }\r
+    }\r
 }\r