You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by mf...@apache.org on 2012/05/30 18:42:51 UTC

svn commit: r1344344 - in /rave/branches/model_interfaces: rave-components/rave-commons/src/main/java/org/apache/rave/model/ rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/ rave-components/rave-core/src/main/java/org/ap...

Author: mfranklin
Date: Wed May 30 16:42:50 2012
New Revision: 1344344

URL: http://svn.apache.org/viewvc?rev=1344344&view=rev
Log:
Added List proxy that converts model objects prior to adding them (RAVE-630)

Added:
    rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaAddress.java
      - copied, changed from r1343977, rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonImpl.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/ListProxyFactory.java
    rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/
    rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java
    rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/ListProxyFactoryTest.java
Modified:
    rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaPerson.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java
    rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java
    rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java
    rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml
    rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java

Added: rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java?rev=1344344&view=auto
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java (added)
+++ rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java Wed May 30 16:42:50 2012
@@ -0,0 +1,10 @@
+package org.apache.rave.model;
+
+import org.springframework.core.convert.converter.Converter;
+
+/**
+ * Converts a source type to a target
+ */
+public interface ModelConverter<S,T> extends Converter<S,T> {
+    Class<S> getSourceType();
+}

Modified: rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java (original)
+++ rave/branches/model_interfaces/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java Wed May 30 16:42:50 2012
@@ -24,6 +24,7 @@ import java.util.List;
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 
+import org.apache.rave.exception.NotSupportedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.IncorrectResultSizeDataAccessException;
@@ -95,4 +96,25 @@ public class JpaUtil {
         query.setFirstResult(offset).setMaxResults(pageSize);
         return query.getResultList();
     }
+
+    /**
+     * Clears an original list and adds all items from the passed in base type list
+     * @param target the list to replace
+     * @param newList the list to replace with
+     * @param clazz the target class
+     * @param <E> The base type
+     * @param <T> The target type
+     */
+    public static <E, T extends E> void clearAndAdd(List<T> target, List<E> newList, Class<T> clazz) {
+        target.clear();
+        if (newList != null) {
+            for (E e : newList) {
+                if (e.getClass().equals(clazz)) {
+                    target.add((T)e);
+                } else {
+                    throw new NotSupportedException("Cannot directly set list composed of non JPA Entities");
+                }
+            }
+        }
+    }
 }

Added: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java?rev=1344344&view=auto
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java (added)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java Wed May 30 16:42:50 2012
@@ -0,0 +1,50 @@
+package org.apache.rave.portal.model;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mfranklin
+ * Date: 5/30/12
+ * Time: 8:28 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface Address {
+    String getCountry();
+
+    void setCountry(String country);
+
+    Float getLatitude();
+
+    void setLatitude(Float latitude);
+
+    Float getLongitude();
+
+    void setLongitude(Float longitude);
+
+    String getLocality();
+
+    void setLocality(String locality);
+
+    String getPostalCode();
+
+    void setPostalCode(String postalCode);
+
+    String getRegion();
+
+    void setRegion(String region);
+
+    String getStreetAddress();
+
+    void setStreetAddress(String streetAddress);
+
+    String getQualifier();
+
+    void setQualifier(String qualifier);
+
+    String getFormatted();
+
+    void setFormatted(String formatted);
+
+    Boolean getPrimary();
+
+    void setPrimary(Boolean primary);
+}

Copied: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaAddress.java (from r1343977, rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java)
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaAddress.java?p2=rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaAddress.java&p1=rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java&r1=1343977&r2=1344344&rev=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java (original)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaAddress.java Wed May 30 16:42:50 2012
@@ -18,22 +18,18 @@
  */
 package org.apache.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
+import javax.persistence.*;
 
 /**
  */
 @Entity
+@NamedQueries(value = {
+        @NamedQuery(name = JpaAddress.FIND_BY_STREET_CITY_COUNTRY, query = "select a from JpaAddress a where a.streetAddress=:street and a.locality=:city and a.country=:country")
+})
 @Table(name = "address")
-public class Address {
+public class JpaAddress implements Address {
+
+    public static final String FIND_BY_STREET_CITY_COUNTRY = "findByStreetCityCountry";
 
     @Id
     @Column(name = "entity_id")
@@ -90,82 +86,102 @@ public class Address {
         this.entityId = entityId;
     }
 
+    @Override
     public String getCountry() {
         return country;
     }
 
+    @Override
     public void setCountry(String country) {
         this.country = country;
     }
 
+    @Override
     public Float getLatitude() {
         return latitude;
     }
 
+    @Override
     public void setLatitude(Float latitude) {
         this.latitude = latitude;
     }
 
+    @Override
     public Float getLongitude() {
         return longitude;
     }
 
+    @Override
     public void setLongitude(Float longitude) {
         this.longitude = longitude;
     }
 
+    @Override
     public String getLocality() {
         return locality;
     }
 
+    @Override
     public void setLocality(String locality) {
         this.locality = locality;
     }
 
+    @Override
     public String getPostalCode() {
         return postalCode;
     }
 
+    @Override
     public void setPostalCode(String postalCode) {
         this.postalCode = postalCode;
     }
 
+    @Override
     public String getRegion() {
         return region;
     }
 
+    @Override
     public void setRegion(String region) {
         this.region = region;
     }
 
+    @Override
     public String getStreetAddress() {
         return streetAddress;
     }
 
+    @Override
     public void setStreetAddress(String streetAddress) {
         this.streetAddress = streetAddress;
     }
 
+    @Override
     public String getQualifier() {
         return qualifier;
     }
 
+    @Override
     public void setQualifier(String qualifier) {
         this.qualifier = qualifier;
     }
 
+    @Override
     public String getFormatted() {
         return formatted;
     }
 
+    @Override
     public void setFormatted(String formatted) {
         this.formatted = formatted;
     }
 
+    @Override
     public Boolean getPrimary() {
         return primary;
     }
 
+    @Override
     public void setPrimary(Boolean primary) {
         this.primary = primary;
     }

Modified: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaPerson.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaPerson.java?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaPerson.java (original)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/JpaPerson.java Wed May 30 16:42:50 2012
@@ -18,29 +18,16 @@
  */
 package org.apache.rave.portal.model;
 
-import org.apache.rave.exception.NotSupportedException;
 import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ListProxyFactory;
 import org.apache.rave.util.CollectionUtils;
 
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
+import javax.persistence.*;
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.apache.rave.persistence.jpa.util.JpaUtil.clearAndAdd;
+
 /**
  * Represents a person in the persistence context
  */
@@ -114,7 +101,7 @@ public class JpaPerson implements BasicE
     @JoinTable(name = "person_address_jn",
             joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "entity_id"),
             inverseJoinColumns = @JoinColumn(name="person_id", referencedColumnName = "entity_id"))
-    protected List<Address> addresses;
+    protected List<JpaAddress> addresses;
 
     @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
     @JoinColumn(name="person_id", referencedColumnName = "entity_id")
@@ -130,6 +117,7 @@ public class JpaPerson implements BasicE
             inverseJoinColumns = @JoinColumn(name = "followed_id", referencedColumnName = "entity_id"))
     protected List<JpaPerson> friends;
 
+
     public Long getEntityId() {
         return entityId;
     }
@@ -249,13 +237,17 @@ public class JpaPerson implements BasicE
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<Address> getAddresses() {
-        return addresses;
+        return ListProxyFactory.getInstance().createProxyList(Address.class, addresses);
     }
 
     @Override
     public void setAddresses(List<Address> addresses) {
-        this.addresses = addresses;
+        if(this.addresses == null) {
+            this.addresses = new ArrayList<JpaAddress>();
+        }
+        clearAndAdd(this.addresses, addresses, JpaAddress.class);
     }
 
     @Override
@@ -269,18 +261,17 @@ public class JpaPerson implements BasicE
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<Person> getFriends() {
-        return CollectionUtils.<Person>toBaseTypedList(friends);
+        return ListProxyFactory.getInstance().createProxyList(Person.class, friends);
     }
 
     @Override
     public void setFriends(List<Person> friends) {
-        if (friends != null) {
-            if(this.friends == null) {
-                this.friends = new ArrayList<JpaPerson>();
-            }
-            clearAndAddPeople(this.friends, friends);
+        if(this.friends == null) {
+            this.friends = new ArrayList<JpaPerson>();
         }
+        clearAndAdd(this.friends, friends, JpaPerson.class);
     }
 
     @Override
@@ -309,16 +300,5 @@ public class JpaPerson implements BasicE
     public int hashCode() {
         return entityId != null ? entityId.hashCode() : 0;
     }
-
-    private static void clearAndAddPeople(List<JpaPerson> target, List<Person> friends) {
-        target.clear();
-        for (Person p : friends) {
-            if (p instanceof JpaPerson) {
-                target.add((JpaPerson)p);
-            } else {
-                throw new NotSupportedException("Cannot directly set Friends list composed of non JPA Entities");
-            }
-        }
-    }
 }
 

Added: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonImpl.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonImpl.java?rev=1344344&view=auto
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonImpl.java (added)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonImpl.java Wed May 30 16:42:50 2012
@@ -0,0 +1,193 @@
+package org.apache.rave.portal.model;
+
+import java.util.List;
+
+public class PersonImpl implements Person{
+
+    protected String username;
+    protected String email;
+    protected String displayName;
+    protected String additionalName;
+    protected String familyName;
+    protected String givenName;
+    protected String honorificPrefix;
+    protected String honorificSuffix;
+    protected String preferredName;
+    protected String aboutMe;
+    protected String status;
+    protected List<Address> addresses;
+    protected List<Organization> organizations;
+    protected List<PersonProperty> properties;
+    protected List<Person> friends;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getAdditionalName() {
+        return additionalName;
+    }
+
+    public void setAdditionalName(String additionalName) {
+        this.additionalName = additionalName;
+    }
+
+    public String getFamilyName() {
+        return familyName;
+    }
+
+    public void setFamilyName(String familyName) {
+        this.familyName = familyName;
+    }
+
+    public String getGivenName() {
+        return givenName;
+    }
+
+    public void setGivenName(String givenName) {
+        this.givenName = givenName;
+    }
+
+    public String getHonorificPrefix() {
+        return honorificPrefix;
+    }
+
+    public void setHonorificPrefix(String honorificPrefix) {
+        this.honorificPrefix = honorificPrefix;
+    }
+
+    public String getHonorificSuffix() {
+        return honorificSuffix;
+    }
+
+    public void setHonorificSuffix(String honorificSuffix) {
+        this.honorificSuffix = honorificSuffix;
+    }
+
+    public String getPreferredName() {
+        return preferredName;
+    }
+
+    public void setPreferredName(String preferredName) {
+        this.preferredName = preferredName;
+    }
+
+    public String getAboutMe() {
+        return aboutMe;
+    }
+
+    public void setAboutMe(String aboutMe) {
+        this.aboutMe = aboutMe;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public List<Address> getAddresses() {
+        return addresses;
+    }
+
+    public void setAddresses(List<Address> addresses) {
+        this.addresses = addresses;
+    }
+
+    public List<Organization> getOrganizations() {
+        return organizations;
+    }
+
+    public void setOrganizations(List<Organization> organizations) {
+        this.organizations = organizations;
+    }
+
+    public List<PersonProperty> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<PersonProperty> properties) {
+        this.properties = properties;
+    }
+
+    public List<Person> getFriends() {
+        return friends;
+    }
+
+    public void setFriends(List<Person> friends) {
+        this.friends = friends;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PersonImpl)) return false;
+
+        PersonImpl person = (PersonImpl) o;
+
+        if (aboutMe != null ? !aboutMe.equals(person.aboutMe) : person.aboutMe != null) return false;
+        if (additionalName != null ? !additionalName.equals(person.additionalName) : person.additionalName != null)
+            return false;
+        if (addresses != null ? !addresses.equals(person.addresses) : person.addresses != null) return false;
+        if (displayName != null ? !displayName.equals(person.displayName) : person.displayName != null) return false;
+        if (email != null ? !email.equals(person.email) : person.email != null) return false;
+        if (familyName != null ? !familyName.equals(person.familyName) : person.familyName != null) return false;
+        if (friends != null ? !friends.equals(person.friends) : person.friends != null) return false;
+        if (givenName != null ? !givenName.equals(person.givenName) : person.givenName != null) return false;
+        if (honorificPrefix != null ? !honorificPrefix.equals(person.honorificPrefix) : person.honorificPrefix != null)
+            return false;
+        if (honorificSuffix != null ? !honorificSuffix.equals(person.honorificSuffix) : person.honorificSuffix != null)
+            return false;
+        if (organizations != null ? !organizations.equals(person.organizations) : person.organizations != null)
+            return false;
+        if (preferredName != null ? !preferredName.equals(person.preferredName) : person.preferredName != null)
+            return false;
+        if (properties != null ? !properties.equals(person.properties) : person.properties != null) return false;
+        if (status != null ? !status.equals(person.status) : person.status != null) return false;
+        if (username != null ? !username.equals(person.username) : person.username != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = username != null ? username.hashCode() : 0;
+        result = 31 * result + (email != null ? email.hashCode() : 0);
+        result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
+        result = 31 * result + (additionalName != null ? additionalName.hashCode() : 0);
+        result = 31 * result + (familyName != null ? familyName.hashCode() : 0);
+        result = 31 * result + (givenName != null ? givenName.hashCode() : 0);
+        result = 31 * result + (honorificPrefix != null ? honorificPrefix.hashCode() : 0);
+        result = 31 * result + (honorificSuffix != null ? honorificSuffix.hashCode() : 0);
+        result = 31 * result + (preferredName != null ? preferredName.hashCode() : 0);
+        result = 31 * result + (aboutMe != null ? aboutMe.hashCode() : 0);
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (addresses != null ? addresses.hashCode() : 0);
+        result = 31 * result + (organizations != null ? organizations.hashCode() : 0);
+        result = 31 * result + (properties != null ? properties.hashCode() : 0);
+        result = 31 * result + (friends != null ? friends.hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file

Modified: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java (original)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java Wed May 30 16:42:50 2012
@@ -352,17 +352,16 @@ public class User extends JpaPerson impl
      * have a User object and want to pass on the Person data without the User class data (like password, etc)
      *
      * @return a Person object representing the data contained in this class
-     */
+     */     //TODO:  UNCOMMENT & FIX ONCE USER IS AN INTERFACE RAVE-630
     public Person toPerson() {
-        JpaPerson p = new JpaPerson();
+        PersonImpl p = new PersonImpl();
         p.setAboutMe(this.getAboutMe());
         p.setAdditionalName(this.getAdditionalName());
-        p.setAddresses(this.getAddresses());
+        //p.setAddresses(this.getAddresses());
         p.setDisplayName(this.getDisplayName());
         p.setEmail(this.getEmail());
-        p.setEntityId(this.getEntityId());
         p.setFamilyName(this.getFamilyName());
-        p.setFriends(this.getFriends());
+        //p.setFriends(this.getFriends());
         p.setGivenName(this.getGivenName());
         p.setHonorificPrefix(this.getHonorificPrefix());
         p.setHonorificSuffix(this.getHonorificSuffix());

Modified: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java (original)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java Wed May 30 16:42:50 2012
@@ -1,5 +1,6 @@
 package org.apache.rave.portal.model.conversion;
 
+import org.apache.rave.model.ModelConverter;
 import org.apache.rave.portal.model.JpaPerson;
 import org.apache.rave.portal.model.Person;
 import org.springframework.core.convert.converter.Converter;
@@ -17,7 +18,7 @@ import static org.apache.rave.persistenc
  * Converts from a {@link org.apache.rave.portal.model.Person} to a {@link org.apache.rave.portal.model.JpaPerson}
  */
 @Component
-public class JpaPersonConverter implements Converter<Person, JpaPerson> {
+public class JpaPersonConverter implements ModelConverter<Person, JpaPerson> {
     @PersistenceContext
     private EntityManager manager;
 
@@ -26,8 +27,14 @@ public class JpaPersonConverter implemen
         return source instanceof JpaPerson ? (JpaPerson)source : createEntity(source);
     }
 
+    @Override
+    public Class<Person> getSourceType() {
+        return Person.class;
+    }
+
     private JpaPerson createEntity(Person source) {
-        JpaPerson converted;TypedQuery<JpaPerson> query = manager.createNamedQuery(JpaPerson.FIND_BY_USERNAME, JpaPerson.class);
+        JpaPerson converted;
+        TypedQuery<JpaPerson> query = manager.createNamedQuery(JpaPerson.FIND_BY_USERNAME, JpaPerson.class);
         query.setParameter(JpaPerson.USERNAME_PARAM, source.getUsername());
         converted = getSingleResult(query.getResultList());
 

Added: rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/ListProxyFactory.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/ListProxyFactory.java?rev=1344344&view=auto
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/ListProxyFactory.java (added)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/conversion/ListProxyFactory.java Wed May 30 16:42:50 2012
@@ -0,0 +1,85 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Creates a {@link java.util.List} proxy that converts the added object to an entity
+ */
+@Component
+public class ListProxyFactory {
+
+    //Workaround for inability to access spring context without a lot of machinery
+    //Will allow for a getInstance method to be called.  this is needed because the
+    //Converters are all Spring beans with their own dependencies.
+    private static ListProxyFactory instance;
+
+    Map<Class<?>, Converter> converterMap;
+
+    @Autowired
+    public ListProxyFactory(List<ModelConverter> converters) {
+        converterMap = new HashMap<Class<?>, Converter>();
+        for(ModelConverter converter : converters) {
+            converterMap.put(converter.getSourceType(), converter);
+        }
+        instance = this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <E, T extends E> List createProxyList(Class<E> targetType, List<T> underlyingList) {
+        return (List) Proxy.newProxyInstance(this.getClass().getClassLoader(),
+                new Class<?>[]{List.class},
+                new ListInvocationHandler<E, T>(converterMap.get(targetType), underlyingList));
+    }
+
+    public static ListProxyFactory getInstance() {
+        if(instance == null) {
+            throw new IllegalStateException("Proxy factory not yet set by the Spring context");
+        }
+        return instance;
+    }
+
+
+    public static class ListInvocationHandler<S,T> implements InvocationHandler {
+
+        public static final String ADD_METHOD = "add";
+        public static final String SET_METHOD = "set";
+        public static final String ADD_ALL_METHOD = "addAll";
+
+        private Converter<S, T> converter;
+        private List<T> underlying;
+        public ListInvocationHandler(Converter<S, T> converter, List<T> underlying) {
+            this.converter = converter;
+            this.underlying = underlying;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable {
+            String methodName = method.getName();
+            int convertIndex = method.getParameterTypes().length == 1 ? 0 : 1;
+            if(ADD_METHOD.equals(methodName) || SET_METHOD.equals(methodName)) {
+                parameters[convertIndex] = converter.convert((S)parameters[convertIndex]);
+            } else if(ADD_ALL_METHOD.equals(methodName)) {
+                convertAll((List)parameters[convertIndex]);
+            }
+            return method.invoke(underlying, parameters);
+        }
+
+        @SuppressWarnings("unchecked")
+        private void convertAll(List<S> parameter) {
+            for(int i=0; i<parameter.size(); i++) {
+                parameter.set(i, (S)converter.convert(parameter.get(i)));
+            }
+        }
+    }
+}

Added: rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java?rev=1344344&view=auto
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java (added)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java Wed May 30 16:42:50 2012
@@ -0,0 +1,7 @@
+package org.apache.rave.portal.model.conversion;
+
+/**
+ *
+ */
+public class JpaPersonConverterTest {
+}

Added: rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/ListProxyFactoryTest.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/ListProxyFactoryTest.java?rev=1344344&view=auto
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/ListProxyFactoryTest.java (added)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/conversion/ListProxyFactoryTest.java Wed May 30 16:42:50 2012
@@ -0,0 +1,116 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.model.PersonImpl;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+/**
+ */
+public class ListProxyFactoryTest {
+
+    @Test(expected = IllegalStateException.class)
+    public void unsetInstance() {
+        ListProxyFactory.getInstance();
+    }
+
+    @Test
+    public void createProxy() {
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        replay(converterMock);
+        List<PersonImpl> underlying = new ArrayList<PersonImpl>();
+        new ListProxyFactory(converters);
+
+        List<Person> personProxy = ListProxyFactory.getInstance().createProxyList(Person.class, underlying);
+        assertThat(Proxy.isProxyClass(personProxy.getClass()), is(true));
+    }
+
+    @Test
+    public void proxyAdd() {
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        Person personImpl1 = new PersonImpl();
+        PersonImpl personImpl2 = new PersonImpl();
+        expect(converterMock.convert(personImpl1)).andReturn(personImpl2);
+        replay(converterMock);
+        List<PersonImpl> underlying = createMock(List.class);
+        expect(underlying.add(personImpl2)).andReturn(true);
+        replay(underlying);
+        new ListProxyFactory(converters);
+
+
+        List<Person> personProxy = ListProxyFactory.getInstance().createProxyList(Person.class, underlying);
+        Boolean good = personProxy.add(personImpl1);
+        assertThat(good, is(true));
+        verify(converterMock);
+        verify(underlying);
+    }
+
+    @Test
+    public void proxySet() {
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        Person personImpl1 = new PersonImpl();
+        Person personImpl2 = new PersonImpl();
+        expect(converterMock.convert(personImpl1)).andReturn(personImpl2);
+        replay(converterMock);
+        List<PersonImpl> underlying = createMock(List.class);
+        expect(underlying.set(0, (PersonImpl)personImpl2)).andReturn((PersonImpl) personImpl2);
+        replay(underlying);
+        new ListProxyFactory(converters);
+
+        List<Person> personProxy = ListProxyFactory.getInstance().createProxyList(Person.class, underlying);
+        Person good = personProxy.set(0, personImpl1);
+        assertThat(good, is(sameInstance(personImpl2)));
+        verify(converterMock);
+        verify(underlying);
+    }
+
+    @Test
+    public void proxyAddAll() {
+
+        Person personImpl1 = new PersonImpl();
+        Person personImpl2 = new PersonImpl();
+        Person personImpl3 = new PersonImpl();
+        Person personImpl4 = new PersonImpl();
+
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        expect(converterMock.convert(personImpl1)).andReturn(personImpl2);
+        expect(converterMock.convert(personImpl3)).andReturn(personImpl4);
+        replay(converterMock);
+
+        List<Person> toAdd = new ArrayList<Person>();
+        toAdd.add(personImpl1);
+        toAdd.add(personImpl3);
+
+        List<PersonImpl> underlying = createMock(List.class);
+        expect(underlying.addAll(isA(List.class))).andReturn(true);
+        replay(underlying);
+        new ListProxyFactory(converters);
+
+        List<Person> personProxy = ListProxyFactory.getInstance().createProxyList(Person.class, underlying);
+        Boolean good = personProxy.addAll(toAdd);
+        assertThat(good, is(true));
+        verify(converterMock);
+        verify(underlying);
+    }
+}

Modified: rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java (original)
+++ rave/branches/model_interfaces/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java Wed May 30 16:42:50 2012
@@ -303,7 +303,8 @@ public class DefaultUserServiceTest {
         expect(userRepository.getAllByAddedWidget(VALID_WIDGET_ID)).andReturn(userList);
         replay(userRepository);
 
-        assertThat(service.getAllByAddedWidget(VALID_WIDGET_ID), is(personList));
+        List<Person> allByAddedWidget = service.getAllByAddedWidget(VALID_WIDGET_ID);
+        assertThat(allByAddedWidget, is(equalTo(personList)));
         
         verify(userRepository);
     }

Modified: rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml (original)
+++ rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml Wed May 30 16:42:50 2012
@@ -27,7 +27,7 @@
       <class>org.apache.rave.portal.model.Group</class>
       <class>org.apache.rave.portal.model.PersonAssociation</class>
       <class>org.apache.rave.portal.model.PersonProperty</class>
-      <class>org.apache.rave.portal.model.Address</class>
+      <class>org.apache.rave.portal.model.JpaAddress</class>
       <class>org.apache.rave.portal.model.Organization</class>
       <class>org.apache.rave.opensocial.model.ApplicationData</class>
       <class>org.apache.rave.opensocial.repository.impl.JpaApplicationDataRepository$JpaSerializableApplicationData</class>

Modified: rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java
URL: http://svn.apache.org/viewvc/rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java?rev=1344344&r1=1344343&r2=1344344&view=diff
==============================================================================
--- rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java (original)
+++ rave/branches/model_interfaces/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java Wed May 30 16:42:50 2012
@@ -253,7 +253,7 @@ public class FieldRestrictingPersonTest 
 
     @Test
     public void getGender_null() {
-        JpaPerson testPerson = getTestPerson();
+        org.apache.rave.portal.model.Person testPerson = getTestPerson();
         testPerson.setProperties(new ArrayList<PersonProperty>());
         Person p = new FieldRestrictingPerson(testPerson, getFieldSet(Person.Field.GENDER));
         assertThat(p.getGender(), is(nullValue()));
@@ -303,19 +303,19 @@ public class FieldRestrictingPersonTest 
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.LIVING_ARRANGEMENT));
         assertThat(p.getLivingArrangement(), is(nullValue()));
     }
-    
+
     @Test
     public void getLookingFor_set() {
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.LOOKING_FOR));
         assertThat(p.getLookingFor().size(), is(equalTo(1)));
     }
-    
+
     @Test
     public void getMovies_set() {
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.MOVIES));
         assertThat(p.getMovies().isEmpty(), is(true));
     }
-    
+
     @Test
     public void getMusic_set() {
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.MUSIC));
@@ -485,17 +485,17 @@ public class FieldRestrictingPersonTest 
     public void setMovies() {
         new FieldRestrictingPerson(null, null).setMovies(new ArrayList<String>());
     }
-    
+
     @Test(expected = NotSupportedException.class)
     public void setLookingFor() {
         new FieldRestrictingPerson(null, null).setLookingFor(new ArrayList<org.apache.shindig.protocol.model.Enum<LookingFor>>());
     }
-    
+
     @Test(expected = NotSupportedException.class)
     public void setLivingArrangement() {
         new FieldRestrictingPerson(null, null).setLivingArrangement(SUFFIX);
     }
-    
+
     @Test(expected = NotSupportedException.class)
     public void setUpdated() {
         new FieldRestrictingPerson(null, null).setUpdated(new Date());
@@ -621,9 +621,8 @@ public class FieldRestrictingPersonTest 
         new FieldRestrictingPerson(null, null).setHappiestWhen(SUFFIX);
     }
 
-    private JpaPerson getTestPerson() {
-        JpaPerson person = new JpaPerson();
-        person.setEntityId(1L);
+    private org.apache.rave.portal.model.Person getTestPerson() {
+        org.apache.rave.portal.model.Person person = new PersonImpl();
         person.setUsername(USERNAME);
         person.setAboutMe(ABOUT_ME);
         person.setAdditionalName(ADDITIONAL_NAME);
@@ -654,7 +653,7 @@ public class FieldRestrictingPersonTest 
         properties.add(new PersonProperty(1L, "currentLocation", QUALIFIER, null, null, null));
         properties.add(new PersonProperty(1L, "account", IM_1, "1", IM_PROVIDER_1, false));
         person.setProperties(properties);
-        org.apache.rave.portal.model.Address address = new org.apache.rave.portal.model.Address();
+        org.apache.rave.portal.model.Address address = new JpaAddress();
         address.setCountry(COUNTRY);
         address.setLatitude(LATITUDE);
         address.setLongitude(LONGITUDE);
@@ -664,7 +663,7 @@ public class FieldRestrictingPersonTest 
         address.setStreetAddress(STREET);
         address.setQualifier(QUALIFIER);
         List<org.apache.rave.portal.model.Address> addresses = new ArrayList<org.apache.rave.portal.model.Address>();
-        addresses.add(new org.apache.rave.portal.model.Address());
+        addresses.add(new JpaAddress());
         addresses.add(address);
         person.setAddresses(addresses);