abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r1205134 - in /abdera/abdera2: activities/src/main/java/org/apache/abdera2/activities/extra/ activities/src/main/java/org/apache/abdera2/activities/io/gson/ activities/src/main/java/org/apache/abdera2/activities/model/ activities/src/main/j...
Date Tue, 22 Nov 2011 19:17:46 GMT
Author: jmsnell
Date: Tue Nov 22 19:17:45 2011
New Revision: 1205134

URL: http://svn.apache.org/viewvc?rev=1205134&view=rev
Log:
javadoc updates, several minor code improvements, ability to generate a Diff of two Activities
objects

Added:
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Difference.java
  (with props)
Modified:
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Jwt.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/PusherCollectionWriter.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/GsonIO.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/MultimapAdapter.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/SimpleAdapter.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASBase.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASObject.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/Activity.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/NoteObject.java
    abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/Objects.java
    abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ASContext.java
Tue Nov 22 19:17:45 2011
@@ -28,11 +28,14 @@ import org.apache.abdera2.common.templat
  * of an Activity Streams object. For example:
  * 
  * Template template = new Template("{?nextPageToken}"};
- * ASObject obj = new ASObject();
- * obj.setProperty("nextPageToken");
- * ASContext ctx = new ASContext(obj);
- * String the_new_iri = template.expand(ctx);
+ * String the_new_iri = 
+ *   template.expand(
+ *     ASContext.create(
+ *       ASObject
+ *         .makeObject()
+ *         .set("nextPageToken","..."));
  * 
+ * Instances are immutable and threadsafe
  */
 public final class ASContext 
   extends AbstractContext {

Added: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Difference.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Difference.java?rev=1205134&view=auto
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Difference.java
(added)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Difference.java
Tue Nov 22 19:17:45 2011
@@ -0,0 +1,112 @@
+package org.apache.abdera2.activities.extra;
+
+import java.util.Map;
+
+import org.apache.abdera2.activities.model.ASBase;
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.misc.Pair;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.MapDifference;
+import com.google.common.collect.MapDifference.ValueDifference;
+import com.google.common.collect.Maps.EntryTransformer;
+
+import static com.google.common.collect.Maps.difference;
+import static com.google.common.collect.Maps.transformEntries;
+import static org.apache.abdera2.activities.extra.Extra.caseTransform;
+
+public final class Difference {
+
+  public static Difference diff(ASBase base1, ASBase base2) {
+    return new Difference(base1,base2);
+  }
+  
+  private static final EntryTransformer<String,Object,Object> transform =
+    caseTransform("objectType","alias");
+  
+  private final Iterable<Pair<String,Pair<Object,Object>>> changed;
+  private final Iterable<Pair<String,Object>> added;
+  private final Iterable<Pair<String,Object>> removed;
+    
+  Difference(ASBase base1, ASBase base2) {
+    MapDifference<String,Object> difference = 
+      difference(
+        transformEntries(base1.toMap(),transform), 
+        transformEntries(base2.toMap(),transform));
+    this.changed = _fieldsChanged(difference);
+    this.added = _fieldsAdded(difference);
+    this.removed = _fieldsRemoved(difference);
+  }
+  
+  public Iterable<Pair<String,Pair<Object,Object>>> changed() {
+    return changed;
+  }
+  
+  public Iterable<Pair<String,Object>> added() {
+    return added;
+  }
+  
+  public Iterable<Pair<String,Object>> removed() {
+    return removed;
+  }
+  
+  public String toString() {
+    return new StringBuilder()
+      .append("Changes: ").append(changed).append('\n')
+      .append("Added:   ").append(added).append('\n')
+      .append("Removed: ").append(removed).append('\n')
+      .toString();
+  }
+  
+  public int hashCode() {
+    return MoreFunctions.genHashCode(1,changed,added,removed);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Difference other = (Difference) obj;
+    if (added == null) {
+      if (other.added != null)
+        return false;
+    } else if (!Iterables.elementsEqual(added, other.added))
+      return false;
+    if (changed == null) {
+      if (other.changed != null)
+        return false;
+    } else if (!Iterables.elementsEqual(changed, other.changed))
+      return false;
+    if (removed == null) {
+      if (other.removed != null)
+        return false;
+    } else if (!Iterables.elementsEqual(removed, other.removed))
+      return false;
+    return true;
+  }
+
+  private Iterable<Pair<String,Pair<Object,Object>>> _fieldsChanged(MapDifference<String,Object>
difference) {
+    Map<String,ValueDifference<Object>> changes = 
+      difference.entriesDiffering();
+    ImmutableSet.Builder<Pair<String,Pair<Object,Object>>> set =
+      ImmutableSet.builder();
+    for (Map.Entry<String, ValueDifference<Object>> entry : changes.entrySet())
{
+      ValueDifference<Object> vd = entry.getValue();
+      set.add(Pair.of(entry.getKey(),Pair.of(vd.leftValue(), vd.rightValue())));
+    }
+    return set.build();
+  }
+  
+  private Iterable<Pair<String,Object>> _fieldsAdded(MapDifference<String,Object>
difference) {
+    return Pair.from(difference.entriesOnlyOnRight());
+  }
+  
+  private Iterable<Pair<String,Object>> _fieldsRemoved(MapDifference<String,Object>
difference) {
+    return Pair.from(difference.entriesOnlyOnLeft());
+  }
+}

Propchange: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Difference.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Extra.java
Tue Nov 22 19:17:45 2011
@@ -38,6 +38,7 @@ import org.apache.abdera2.activities.mod
 import org.apache.abdera2.activities.model.Verb;
 import org.apache.abdera2.common.anno.Name;
 import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.common.misc.MoreFunctions;
 import org.apache.abdera2.common.selector.AbstractSelector;
 import org.apache.abdera2.common.selector.PropertySelector;
 import org.apache.abdera2.common.selector.Selector;
@@ -50,11 +51,14 @@ import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.MapDifference;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Maps.EntryTransformer;
 
 import static com.google.common.base.Predicates.*;
 import static org.apache.abdera2.activities.model.objects.Objects.*;
-import static org.apache.abdera2.common.misc.Comparisons.*;
 import static org.apache.abdera2.common.misc.MorePredicates.*;
 import static com.google.common.base.Preconditions.*;
 
@@ -724,10 +728,26 @@ public final class Extra {
   
   /**
    * Equivalence instance that can be used to check the equivalence of two
-   * ASObjects
+   * ASObjects. This version also checks the downstreamDuplicates and 
+   * upstreamDuplicates values to determine identity equivalence.
    */
   public static final Equivalence<ASObject> IDENTITY_WITH_DUPLICATES_EQUIVALENCE =
identityWithDuplicates();
   
+  static final EntryTransformer<String,Object,Object> lower_val = 
+    caseTransform("alias","objectType");
+  
+  public static EntryTransformer<String,Object,Object> caseTransform(
+    final String... lowerFields) {
+    final ImmutableSet<String> fields = ImmutableSet.copyOf(lowerFields);
+    return new EntryTransformer<String,Object,Object>() {
+      public Object transformEntry(String key, Object value) {
+        return fields.contains(key) ?
+          value.toString().toLowerCase() :
+          value;
+      }
+    };
+  }
+  
   /**
    * Two ASObject's are considered equivalent in identity if 
    * they share the same objectType and id property
@@ -738,36 +758,22 @@ public final class Extra {
   private static Equivalence<ASObject> identity() {
     return new Equivalence<ASObject>() {
       protected boolean doEquivalent(ASObject a, ASObject b) {
-        if (bothAreNull(a,b)) return true;
-        if (onlyOneIsNull(a,b)) return false;
-        String aot = a.getObjectType();
-        String bot = b.getObjectType();
-        if (bothAreNull(aot,bot)) return true;
-        if (onlyOneIsNull(aot,bot)) return false;
-        if (!aot.equalsIgnoreCase(bot)) return false;
-        String aid = a.getId();
-        String bid = b.getId();
-        if (onlyOneIsNull(aid,bid)) return false;
-        if (neitherIsNull(aid,bid)) {
-          if (aid.equals(bid)) return true;
-          else return false;
-        }
-        String adn = a.getDisplayName();
-        String bdn = b.getDisplayName();
-        if (bothAreNull(adn,bdn)) return true;
-        if (onlyOneIsNull(adn,bdn)) return false;
-        if (!adn.equals(bdn)) return false;
-        return true;
+        Selector<Map.Entry<String,Object>> filter = 
+          ASBase.withFields("id","alias","objectType");
+        Map<String,Object> map1 = Maps.transformEntries(a.toMap(filter),lower_val);
+        Map<String,Object> map2 = Maps.transformEntries(b.toMap(filter),lower_val);
+        MapDifference<String,Object> diff = 
+          Maps.difference(map1, map2);
+        return ((diff.entriesInCommon().containsKey("alias") ||
+            diff.entriesInCommon().containsKey("id")) && 
+            !diff.entriesDiffering().containsKey("objectType") && 
+            !diff.entriesDiffering().containsKey("id"));
       }
       protected int doHash(ASObject t) {
-        String id = t.getId();
-        String objectType = t.getObjectType();
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        result = prime * result
-            + ((objectType == null) ? 0 : objectType.hashCode());
-        return result;
+        return MoreFunctions.genHashCode(
+          1, t.getId(), 
+          t.getProperty("alias"), 
+          t.getObjectType());
       }
     };
   }
@@ -779,22 +785,17 @@ public final class Extra {
           return true;
         Iterable<String> aids = a.getKnownIds();
         Iterable<String> bids = b.getKnownIds();
-        Iterable<String> cids = 
+        // if is empty, it's not a duplicate, so return false
+        // if isn't empty, they are likely duplicates, return true
+        return !Iterables.isEmpty(
           Iterables.filter(
-            aids, in((Set<String>)bids));
-        // if cids is empty, it's not a duplicate, so return false
-        // if cids isn't empty, they are likely duplicates, return true
-        return !Iterables.isEmpty(cids);
+            aids, in((Set<String>)bids)));
       }
       protected int doHash(ASObject t) {
-        String id = t.getId();
-        String objectType = t.getObjectType();
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        result = prime * result
-            + ((objectType == null) ? 0 : objectType.hashCode());
-        return result;
+        return MoreFunctions.genHashCode(
+            1, t.getId(), 
+            t.getProperty("alias"), 
+            t.getObjectType());
       }
     };
   }

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Jwt.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Jwt.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Jwt.java (original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/Jwt.java Tue
Nov 22 19:17:45 2011
@@ -27,6 +27,9 @@ import org.apache.abdera2.activities.mod
 import org.apache.abdera2.activities.model.IO;
 import org.apache.abdera2.common.security.HashHelper;
 import org.apache.commons.codec.binary.Base64;
+
+import com.google.common.base.Supplier;
+
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -88,6 +91,10 @@ public final class Jwt {
     
   }
 
+  public static String generate(Key key, byte[] claim, Supplier<ASBase> header) {
+    return generate(key,claim,checkNotNull(header).get());
+  }
+  
   public static String generate(Key key, byte[] claim, ASBase header) {
     return generate(Alg.HS256, key, claim, header);
   }
@@ -122,7 +129,12 @@ public final class Jwt {
   
   public static String generate(IO io, Alg alg, Key key, ASBase claim, ASBase header) {
     try {
-      return generate(io,alg,key,io.write(claim).getBytes("UTF-8"),header);
+      return generate(
+        io,
+        alg,
+        key,
+        checkNotNull(io).write(checkNotNull(claim)).getBytes("UTF-8"),
+        header);
     } catch (Throwable t) {
       if (t instanceof RuntimeException)
         throw (RuntimeException)t;
@@ -143,7 +155,8 @@ public final class Jwt {
       checkNotNull(header);
       checkNotNull(header.getProperty("alg"));
       StringBuilder buf = new StringBuilder();
-      String _header = Base64.encodeBase64URLSafeString(io.write(header).getBytes("UTF-8"));
+      String _header = Base64.encodeBase64URLSafeString(
+        checkNotNull(io).write(header).getBytes("UTF-8"));
       String _claim = Base64.encodeBase64URLSafeString(claim);
       buf.append(_header).append('.').append(_claim);
       String mat = buf.toString();

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/PusherCollectionWriter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/PusherCollectionWriter.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/PusherCollectionWriter.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/PusherCollectionWriter.java
Tue Nov 22 19:17:45 2011
@@ -24,7 +24,7 @@ import org.apache.abdera2.activities.mod
 import org.apache.abdera2.common.pusher.Pusher;
 
 /**
- * Simple CollectionWriter implemention that wraps a Pusher object. 
+ * Simple CollectionWriter implementation that wraps a Pusher object. 
  * Calls to writeObject/writeObjects are sent through to the pusher.push 
  * and pusher.pushAll methods. The writeHeader and complete methods are 
  * ignored.

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/GsonIO.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/GsonIO.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/GsonIO.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/GsonIO.java
Tue Nov 22 19:17:45 2011
@@ -84,32 +84,30 @@ public class GsonIO extends IO {
   }
   
   static Gson gson(Boolean pretty, BaseAdapter asbs, Iterable<TypeAdapter<?>>
adapters) {
-    GsonBuilder gb = new GsonBuilder();    
-    gb.registerTypeHierarchyAdapter(Verb.class, new VerbAdapter());
-    gb.registerTypeHierarchyAdapter(Lang.class, new LangAdapter());
-    gb.registerTypeHierarchyAdapter(ASBase.class,  asbs);  
-    gb.registerTypeHierarchyAdapter(Multimap.class, new MultimapAdapter());
-    gb.registerTypeHierarchyAdapter(MimeType.class, new MimeTypeAdapter());
-    gb.registerTypeAdapter(ASBase.class, asbs);
-    gb.registerTypeAdapter(Date.class, new DateAdapter());
-    gb.registerTypeAdapter(DateTime.class, new DateTimeAdapter());
-    gb.registerTypeAdapter(Duration.class, new DurationAdapter());
-    gb.registerTypeAdapter(Interval.class, new IntervalAdapter());
-    gb.registerTypeAdapter(Activity.class,  asbs);
-    gb.registerTypeAdapter(PlaceObject.class, asbs);
-    gb.registerTypeAdapter(Mood.class, asbs);
-    gb.registerTypeAdapter(Address.class, asbs);
-    gb.registerTypeAdapter(IRI.class, new IriAdapter());
-    gb.registerTypeAdapter(IsoPosition.class, new PositionAdapter());
-    gb.registerTypeAdapter(EntityTag.class, new EntityTagAdapter());
-    gb.registerTypeAdapter(Template.class, new TemplateAdapter());
-    gb.registerTypeAdapter(MimeType.class, new MimeTypeAdapter());
-    for(TypeAdapter<?> adapter : adapters) {
-      if (adapter instanceof GsonTypeAdapter) {
+    GsonBuilder gb = new GsonBuilder()   
+      .registerTypeHierarchyAdapter(Verb.class, new VerbAdapter())
+      .registerTypeHierarchyAdapter(Lang.class, new LangAdapter())
+      .registerTypeHierarchyAdapter(ASBase.class,  asbs)
+      .registerTypeHierarchyAdapter(Multimap.class, new MultimapAdapter())
+      .registerTypeHierarchyAdapter(MimeType.class, new MimeTypeAdapter())
+      .registerTypeAdapter(ASBase.class, asbs)
+      .registerTypeAdapter(Date.class, new DateAdapter())
+      .registerTypeAdapter(DateTime.class, new DateTimeAdapter())
+      .registerTypeAdapter(Duration.class, new DurationAdapter())
+      .registerTypeAdapter(Interval.class, new IntervalAdapter())
+      .registerTypeAdapter(Activity.class,  asbs)
+      .registerTypeAdapter(PlaceObject.class, asbs)
+      .registerTypeAdapter(Mood.class, asbs)
+      .registerTypeAdapter(Address.class, asbs)
+      .registerTypeAdapter(IRI.class, new IriAdapter())
+      .registerTypeAdapter(IsoPosition.class, new PositionAdapter())
+      .registerTypeAdapter(EntityTag.class, new EntityTagAdapter())
+      .registerTypeAdapter(Template.class, new TemplateAdapter())
+      .registerTypeAdapter(MimeType.class, new MimeTypeAdapter());
+    for(TypeAdapter<?> adapter : adapters)
+      if (adapter instanceof GsonTypeAdapter)
         gb.registerTypeAdapter(
           adapter.getAdaptedClass(), adapter);
-      }
-    }
     gb.enableComplexMapKeySerialization();
     if (pretty)
       gb.setPrettyPrinting();
@@ -132,11 +130,11 @@ public class GsonIO extends IO {
   }
 
   public <T extends ASBase>T read(Reader reader) {
-    return (T)gson.fromJson(reader, ASBase.class);
+    return gson.<T>fromJson(reader, ASBase.class);
   }
   
   public <T extends ASBase>T read(String json) {
-    return (T)gson.fromJson(json, ASBase.class);
+    return gson.<T>fromJson(json, ASBase.class);
   }
   
   public Activity readActivity(Reader reader) {
@@ -156,11 +154,11 @@ public class GsonIO extends IO {
   }
   
   public <T extends ASObject>T readObject(Reader reader) {
-    return (T)gson.fromJson(reader, ASObject.class);
+    return gson.<T>fromJson(reader, ASObject.class);
   }
   
   public <T extends ASObject>T readObject(String json) {
-    return (T)gson.fromJson(json, ASObject.class);
+    return gson.<T>fromJson(json, ASObject.class);
   }
   
   public MediaLink readMediaLink(Reader reader) {
@@ -190,25 +188,26 @@ public class GsonIO extends IO {
     ASBase header,
     Iterable<ASObject> objects) {
     try {
-      JsonWriter writer = new JsonWriter(out);
-      writer.beginObject();
+      JsonWriter writer = 
+        new JsonWriter(out)
+          .beginObject();
       if (header != null) {
         for (String name : header) {
           Object val = header.getProperty(name);
-          writer.name(name);
           if (val != null) {
+            writer.name(name);
             gson.toJson(val,val.getClass(),writer);
-          } else writer.nullValue();
+          }
+          else writer.nullValue();
         }
       }
-      writer.name("items");
-      writer.beginArray();
-      for (ASObject obj : objects) {
+      writer.name("items")
+            .beginArray();
+      for (ASObject obj : objects)
         gson.toJson(obj,ASBase.class,writer);
-      }
-      writer.endArray();
-      writer.endObject();
-      writer.flush();
+      writer.endArray()
+            .endObject()
+            .flush();
       if (autoclose)
         writer.close();
     } catch (IOException t) {
@@ -240,8 +239,8 @@ public class GsonIO extends IO {
     public void complete() {
       try {
         if (_items) writer.endArray();
-        writer.endObject();
-        writer.flush();
+        writer.endObject()
+              .flush();
         if (autoclose) 
           writer.close();
       } catch (IOException e) {
@@ -252,9 +251,9 @@ public class GsonIO extends IO {
     protected void write(String name, Object val) {
       try {
         writer.name(name);
-        if (val != null) {
+        if (val != null)
           gson.toJson(val,val.getClass(),writer);
-        } else writer.nullValue();
+        else writer.nullValue();
       } catch (IOException e) {
         throw new RuntimeException(e);
       }
@@ -262,8 +261,8 @@ public class GsonIO extends IO {
     @Override
     protected void startItems() {
       try {
-        writer.name("items");
-        writer.beginArray();
+        writer.name("items")
+              .beginArray();
       } catch (IOException e) {
         throw new RuntimeException(e);
       }

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/MultimapAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/MultimapAdapter.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/MultimapAdapter.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/MultimapAdapter.java
Tue Nov 22 19:17:45 2011
@@ -24,6 +24,8 @@ import java.util.Map;
 import org.apache.abdera2.activities.model.ASBase;
 import org.apache.abdera2.common.misc.ExceptionHelper;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Multimap;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonDeserializationContext;
@@ -49,6 +51,29 @@ class MultimapAdapter
       return context.serialize(src.asMap(), Map.class);
   }
 
+  protected static ImmutableList<Object> arraydes(
+    JsonArray array,
+    JsonDeserializationContext context) {
+    ImmutableList.Builder<Object> builder = 
+      ImmutableList.builder();
+    for (JsonElement child : array)
+      if (child.isJsonArray())
+        builder.add(arraydes(child.getAsJsonArray(),context));
+      else if (child.isJsonObject())
+        builder.add(context.deserialize(child, ASBase.class));
+      else if (child.isJsonPrimitive())
+        builder.add(primdes(child.getAsJsonPrimitive()));
+    return builder.build();
+  }
+  
+  protected static Object primdes(JsonPrimitive prim) {
+    if (prim.isBoolean())
+      return prim.getAsBoolean();
+    else if (prim.isNumber())
+      return prim.getAsNumber();
+    else return prim.getAsString();
+  }
+  
   public Multimap deserialize(
     JsonElement json, 
     Type typeOfT,
@@ -59,33 +84,28 @@ class MultimapAdapter
     for (Map.Entry<String,JsonElement> entry : obj.entrySet()) {
       String key = entry.getKey();
       JsonElement val = entry.getValue();
-      if (val.isJsonArray()) {
-        JsonArray array = val.getAsJsonArray();
-        for (JsonElement el : array) {
-          if (el.isJsonArray()) {       
-          } else if (el.isJsonObject()) {
+      if (val.isJsonArray())
+        for (JsonElement el : val.getAsJsonArray())
+          if (el.isJsonArray())
+            mm.put(key, arraydes(el.getAsJsonArray(),context));
+          else if (el.isJsonObject())
             mm.put(key, context.deserialize(el, ASBase.class));
-          } else if (el.isJsonNull()) {
+          else if (el.isJsonNull())
             mm.put(key, null);
-          } else if (el.isJsonPrimitive()) {
-            JsonPrimitive jp = el.getAsJsonPrimitive();
-            if (jp.isBoolean()) {
-              mm.put(key, jp.getAsBoolean());
-            } else if (jp.isNumber()) {
-              mm.put(key, jp.getAsNumber());
-            } else if (jp.isString()) {
-              mm.put(key, jp.getAsString());
-            }
-          }
-        }
-      }
+          else if (el.isJsonPrimitive())
+            mm.put(key,primdes(el.getAsJsonPrimitive()));
+      else if (val.isJsonObject()) 
+        mm.put(key, context.deserialize(val, ASBase.class));
+      else if (val.isJsonPrimitive())
+        mm.put(key, primdes(val.getAsJsonPrimitive()));
     }
     return mm;
   }  
   
   private static Multimap create(Type typeOfT) {
     try {
-      Class<Multimap> _class = (Class<Multimap>)typeOfT;
+      Class<? extends Multimap> _class = (Class<? extends Multimap>)typeOfT;
+      if (_class == Multimap.class) _class = LinkedHashMultimap.class;
       Method method = _class.getMethod("create");
       return (Multimap) method.invoke(_class);
     } catch (Throwable t) {

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/SimpleAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/SimpleAdapter.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/SimpleAdapter.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/io/gson/SimpleAdapter.java
Tue Nov 22 19:17:45 2011
@@ -24,6 +24,8 @@ import com.google.gson.JsonElement;
 import com.google.gson.JsonParseException;
 import com.google.gson.JsonSerializationContext;
 
+import static com.google.common.base.Preconditions.*;
+
 public abstract class SimpleAdapter<T>
   implements GsonTypeAdapter<T> {
 
@@ -35,10 +37,9 @@ public abstract class SimpleAdapter<T>
   
   @SuppressWarnings("unchecked")
   private static <T>Class<T> _getAdaptedClass(Class<?> _class) {
-    if (_class.isAnnotationPresent(AdaptedType.class)) {
-      AdaptedType at = _class.getAnnotation(AdaptedType.class);
-      return (Class<T>) at.value();
-    } else throw new IllegalArgumentException();
+    checkArgument(_class.isAnnotationPresent(AdaptedType.class));
+    AdaptedType at = _class.getAnnotation(AdaptedType.class);
+    return (Class<T>) at.value();
   }
   
   public SimpleAdapter(Class<T> _class) {

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASBase.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASBase.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASBase.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASBase.java
Tue Nov 22 19:17:45 2011
@@ -20,12 +20,16 @@ package org.apache.abdera2.activities.mo
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.lang.ref.Reference;
 import java.lang.reflect.Constructor;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
 
+import org.apache.abdera2.activities.extra.Difference;
 import org.apache.abdera2.activities.extra.Extra;
 import org.apache.abdera2.common.lang.Lang;
 import org.apache.abdera2.common.misc.ExceptionHelper;
@@ -41,6 +45,8 @@ import com.google.common.base.Optional;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
 import static com.google.common.collect.Maps.filterEntries;
 
 /**
@@ -100,15 +106,34 @@ public class ASBase 
       this(_class,_builder);
       this.map.putAll(map);
     }
+    
+    public Object val(Object val) {
+      if (val == null) return null;
+      else if (val instanceof Supplier)
+        return val(((Supplier<?>)val).get());
+      else if (val instanceof Optional)
+        return val(((Optional<?>)val).get());
+      else if (val instanceof Future) {
+        try {
+          return val(((Future<?>)val).get());
+        } catch (Throwable t) {
+          throw ExceptionHelper.propogate(t);
+        }
+      } else if (val instanceof Callable) {
+        try {
+          return val(((Callable<?>)val).call());
+        } catch (Throwable t) {
+          throw ExceptionHelper.propogate(t);
+        }
+      } else if (val instanceof Reference) {
+        return val(((Reference<?>)val).get());
+      } else return val;
+    }
+    
     public M set(String name, Object val) {
-      if (val != null) {
-        if (val instanceof Supplier)
-          val = ((Supplier<?>)val).get();
-        if (val instanceof Optional)
-          val = ((Optional<?>)val).get();
-        if (val != null)
-          map.put(name,val);
-      }
+      val = val(val);
+      if (val != null)
+        map.put(name,val);
       return (M)this;
     }
     public M set(Pair<String,? extends Object> pair) {
@@ -434,6 +459,19 @@ public class ASBase 
   public Object clone() throws CloneNotSupportedException {
     return this.<ASBase,Builder>template().get();
   }
+  
+  public Map<String,Object> toMap() {
+    return exts;
+  }
+  
+  public Map<String,Object> toMap(
+    Selector<Map.Entry<String,Object>> filter) {
+      return Maps.filterEntries(exts, filter);
+  }
+  
+  public Difference diff(ASBase other) {
+    return Difference.diff(this,other);
+  }
 }
 
 

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASObject.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASObject.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASObject.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/ASObject.java
Tue Nov 22 19:17:45 2011
@@ -20,10 +20,8 @@ package org.apache.abdera2.activities.mo
 import org.joda.time.DateTime;
 
 import java.util.ArrayList;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.abdera2.activities.extra.Extra;
 import org.apache.abdera2.activities.model.objects.EmbeddedExperience;
@@ -36,7 +34,6 @@ import org.apache.abdera2.common.selecto
 
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 
 /**
  * Base class for all Activity Streams Objects.
@@ -665,14 +662,16 @@ public class ASObject extends ASBase {
    * properties
    */
   public Iterable<String> getKnownIds() {
-    Set<String> list = new LinkedHashSet<String>();
+    ImmutableSet.Builder<String> list = ImmutableSet.builder();
     if (has("id")) list.add(getId());
-    Iterables.addAll(list, checkEmpty(getDownstreamDuplicates()));
-    Iterables.addAll(list, checkEmpty(getUpstreamDuplicates()));
-    return list;
+    list.addAll(checkEmpty(getDownstreamDuplicates()));
+    list.addAll(checkEmpty(getUpstreamDuplicates()));
+    return list.build();
   }
   
-  public <T extends ASObject,M extends Builder<T,M>>T as(Class<T> type,
String newObjectType) {
+  public <T extends ASObject,M extends Builder<T,M>>T as(
+    Class<T> type, 
+    String newObjectType) {
     return (T)as(type,withoutFields("objectType"))
       .<T,M>template()
         .objectType(newObjectType).get();

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/Activity.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/Activity.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/Activity.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/Activity.java
Tue Nov 22 19:17:45 2011
@@ -17,8 +17,6 @@
  */
 package org.apache.abdera2.activities.model;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 import java.lang.Iterable;
 
@@ -29,6 +27,7 @@ import org.joda.time.DateTime;
 
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
 
 /**
  * An Activity. Represents some action that has been taken. At it's core,
@@ -367,12 +366,10 @@ public class Activity extends ASObject {
    * can be used, for instance, to quickly determine if a particular 
    * entity is included in the audience of the activity
    */
-  public Iterable<ASObject> getAudience(Audience audience, Selector<ASObject>
selector) {
-    List<ASObject> list = new ArrayList<ASObject>();
-    for (ASObject obj : getAudience(audience))
-      if (selector.apply(obj))
-        list.add(obj);
-    return list;
+  public Iterable<ASObject> getAudience(
+    Audience audience, 
+    Selector<ASObject> selector) {
+    return Iterables.filter(getAudience(audience), selector);
   }  
   
 }

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/NoteObject.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/NoteObject.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/NoteObject.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/NoteObject.java
Tue Nov 22 19:17:45 2011
@@ -49,5 +49,5 @@ public class NoteObject 
   public <X extends NoteObject, M extends ASObject.Builder<X,M>>NoteObject(Map<String,Object>
map,Class<M> _class,Class<X>_obj) {
     super(map,_class,_obj);
   }
-  
+
 }

Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/Objects.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/Objects.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/Objects.java
(original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/model/objects/Objects.java
Tue Nov 22 19:17:45 2011
@@ -36,17 +36,26 @@ public final class Objects {
   public static final ASObject PUBLIC = PUBLIC().get();
   public static final ASObject VIEWER = VIEWER().get();
   public static final ASObject OWNER = OWNER().get();
+  public static final ASObject FOLLOWERS = FOLLOWERS().get();
+  
+  public static ASObjectBuilder ALIASED(String alias) {
+    return ASObject.makeObject().set("alias",alias);
+  }
+  
+  public static ASObjectBuilder FOLLOWERS() {
+    return ALIASED("@followers");
+  }
   
   public static ASObjectBuilder VIEWER() {
-    return ASObject.makeObject("@viewer");
+    return ALIASED("@viewer");
   }
   
   public static ASObjectBuilder OWNER() {
-    return ASObject.makeObject("@owner");
+    return ALIASED("@owner");
   }
   
   public static ASObjectBuilder SELF() {
-    return ASObject.makeObject("@self");
+    return ALIASED("@self");
   }
   
   /**
@@ -54,7 +63,7 @@ public final class Objects {
    * synonymous with @self
    */
   public static ASObjectBuilder ME() {
-    return ASObject.makeObject("@me");
+    return ALIASED("@me");
   }
   
   /**
@@ -62,7 +71,7 @@ public final class Objects {
    * collection of direct contacts
    */
   public static ASObjectBuilder FRIENDS() {
-    return ASObject.makeObject("@friends");
+    return ALIASED("@friends");
   }
   
   /**
@@ -70,7 +79,7 @@ public final class Objects {
    * collection of direct contacts
    */
   public static ASObjectBuilder FRIENDS(String id) {
-    return ASObject.makeObject("@friends").id(id);
+    return ALIASED("@friends").id(id);
   }
   
   /**
@@ -78,21 +87,21 @@ public final class Objects {
    * of extended contacts (e.g. friends of friends)
    */
   public static ASObjectBuilder NETWORK() {
-    return ASObject.makeObject("@network");
+    return ALIASED("@network");
   }
   
   /**
    * Special AS Object that represents everyone. synonymous with @public
    */
   public static ASObjectBuilder ALL() {
-    return ASObject.makeObject("@all");
+    return ALIASED("@all");
   }
   
   /**
    * Special AS Object that represents everyone
    */
   public static ASObjectBuilder PUBLIC() {
-    return ASObject.makeObject("@public");
+    return ALIASED("@public");
   }
   
   /**

Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java?rev=1205134&r1=1205133&r2=1205134&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/misc/Pair.java Tue Nov 22
19:17:45 2011
@@ -71,6 +71,10 @@ public class Pair<K,V> {
     return from(pairs.split(String.format("\\s*%s\\s*",delim)));
   }
   
+  public Object[] toArray() {
+    return new Object[] {first(),second()};
+  }
+  
   @Override
   public int hashCode() {
     return MoreFunctions.genHashCode(1, k,v);
@@ -99,6 +103,17 @@ public class Pair<K,V> {
     return true;
   }
   
+  public String toString() {
+    return 
+    new StringBuilder()
+      .append('[')
+      .append(first())
+      .append(',')
+      .append(second())
+      .append(']')
+      .toString();
+  }
+  
   public static <K,V>PairBuilder<K,V> make() {
     return new PairBuilder<K,V>();
   }



Mime
View raw message