merge-update from trunk
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / User.java
index 1e930e53355a0cf48b7af7b1e0e4c287797fcdca..2e6ad25107d377bb31ef752a39eaa62e766a7524 100644 (file)
@@ -1,8 +1,8 @@
 /**\r
 * Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \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
@@ -13,6 +13,7 @@ import java.util.Collection;
 import java.util.HashSet;\r
 import java.util.Set;\r
 \r
+import javax.persistence.Column;\r
 import javax.persistence.Entity;\r
 import javax.persistence.FetchType;\r
 import javax.persistence.ManyToMany;\r
@@ -32,13 +33,10 @@ import javax.xml.bind.annotation.XmlType;
 import org.apache.log4j.Logger;\r
 import org.hibernate.annotations.Cascade;\r
 import org.hibernate.annotations.CascadeType;\r
-import org.hibernate.annotations.NaturalId;\r
 import org.hibernate.envers.Audited;\r
 import org.hibernate.envers.NotAudited;\r
-\r
-\r
+import org.hibernate.search.annotations.Analyze;\r
 import org.hibernate.search.annotations.Field;\r
-import org.hibernate.search.annotations.Index;\r
 import org.hibernate.search.annotations.Indexed;\r
 import org.hibernate.search.annotations.IndexedEmbedded;\r
 import org.springframework.security.core.GrantedAuthority;\r
@@ -57,7 +55,7 @@ import eu.etaxonomy.cdm.model.agent.Person;
     "accountNonExpired",\r
     "credentialsNonExpired",\r
     "accountNonLocked",\r
-    "person"    \r
+    "person"\r
 })\r
 @XmlRootElement(name = "User")\r
 @Entity\r
@@ -65,219 +63,249 @@ import eu.etaxonomy.cdm.model.agent.Person;
 @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
-       protected User(){\r
-               super();\r
-       }\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
-       @XmlElement(name = "Username")\r
-       @NaturalId\r
-       @Field(index = Index.UN_TOKENIZED)\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)\r
-       @NotAudited\r
-       protected Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();\r
-       \r
-       @XmlElementWrapper(name = "Groups")\r
-       @XmlElement(name = "Group")\r
-       @XmlIDREF\r
-       @XmlSchemaType(name = "IDREF")\r
-       @ManyToMany(fetch = FetchType.LAZY)\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;\r
-       \r
-       private 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
-       @Transient\r
-       public Collection<GrantedAuthority> getAuthorities() {\r
-               if(authorities == null) {\r
-                       initAuthorities();\r
-               }\r
-               return authorities;\r
-       }\r
-\r
-       public String getPassword() {\r
-               return password;\r
-       }\r
-\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
-       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
+    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
+     * 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