Initial Checkin… Activity Streams 1.0 Reference Implementation

This commit is contained in:
James M Snell 2014-04-16 15:27:45 -07:00
commit cc478d748c
101 changed files with 17900 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.classpath
.project
.settings
*/.classpath
*/.project
*/.settings

109
README.md Executable file
View File

@ -0,0 +1,109 @@
# Activity Streams 2.0 Reference Implementation
## Getting Started
Maven:
```xml
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
```
Dependencies:
* gson 2.2.4
* guava 16.0.1
* joda-time 2.3
## Creating an Activity statement
```java
import static com.ibm.common.activitystreams.Makers.activity;
import static com.ibm.common.activitystreams.Makers.object;
public class Example {
public static void main(String... args) {
Activity activity =
activity()
.actor(object("person").id("acct:joe@example.org"))
.object(object("note").content("my note"))
.verb("post")
.get();
}
}
```
The library uses a consistent fluent generator pattern to construct all
object types. Once created, objects are immutable.
## Serializing and Parsing objects
The library has one job: to make it easy to create and parse Activity
Stream objects that are conformant to the Activity Streams 2.0
specification.
The IO object is used to serialize and parse Activity Stream objects.
IO objects are threadsafe and immutable so they can be safely created
once and stored as a static final constant.
```java
package com.ibm.common.activitystreams;
import static com.ibm.common.activitystreams.IO.makeDefaultPrettyPrint;
import static com.ibm.common.activitystreams.Makers.activity;
import static com.ibm.common.activitystreams.Makers.object;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public class Test {
private static final IO io = makeDefaultPrettyPrint();
public static void main(String... args) {
Activity activity =
activity()
.actor(object("person").id("acct:joe@example.org"))
.object(object("note").content("my note"))
.verb("post")
.get();
ByteArrayOutputStream out =
new ByteArrayOutputStream();
// Write it out
activity.writeTo(out, io);
ByteArrayInputStream in =
new ByteArrayInputStream(out.toByteArray());
// Read it in
activity = io.readAsActivity(in);
// Access the properties
TypeValue tv = activity.verb();
System.out.println(tv.id()); // "post"
ASObject actor = activity.firstActor();
System.out.println(actor.id()); // "acct:joe@example.org"
for (ASObject object : activity.object())
System.out.println(object.objectType().id()) // "note"
// iterate all properties
for (String key : activity)
System.out.println(activity.get(key));
}
}
```

138
actions/pom.xml Normal file
View File

@ -0,0 +1,138 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>activitystreams-actions</artifactId>
<name>Activity Streams 2.0 - Actions</name>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<charset>UTF-8</charset>
<additionalparam>-XDignore.symbol.file</additionalparam>
<show>public</show>
<links>
<link>http://www.joda.org/joda-time/apidocs</link>
<link>http://docs.guava-libraries.googlecode.com/git-history/v16.0.1/javadoc/</link>
</links>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Export-Package>com.ibm.common.activitystreams.actions.*</Export-Package>
<Import-Package>
com.ibm.common.activitystreams.*,
com.google.gson.*,
com.google.common.*,
org.joda.time.*
</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<versionRange>[2.3.7,)</versionRange>
<goals>
<goal>manifest</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,180 @@
package com.ibm.common.activitystreams.actions.example;
import static com.ibm.common.activitystreams.Makers.object;
import static com.ibm.common.activitystreams.actions.ActionMakers.METHOD_POST;
import static com.ibm.common.activitystreams.actions.ActionMakers.TARGET_DIALOG;
import static com.ibm.common.activitystreams.actions.ActionMakers.htmlForm;
import static com.ibm.common.activitystreams.actions.ActionMakers.httpAction;
import static com.ibm.common.activitystreams.actions.ActionMakers.intentAction;
import static com.ibm.common.activitystreams.actions.ActionMakers.parameter;
import static com.ibm.common.activitystreams.actions.ActionMakers.staticEmbedAction;
import static com.ibm.common.activitystreams.actions.ActionMakers.styles;
import static com.ibm.common.activitystreams.actions.ActionMakers.typedPayload;
import static com.ibm.common.activitystreams.actions.ActionMakers.urlTemplate;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.ActionsValue;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.TypeValue;
import com.ibm.common.activitystreams.ValueType;
import com.ibm.common.activitystreams.actions.ActionsModule;
import com.ibm.common.activitystreams.actions.EmbedActionHandler;
import com.ibm.common.activitystreams.actions.HttpActionHandler;
import com.ibm.common.activitystreams.actions.Parameter;
import com.ibm.common.activitystreams.actions.ParametersValue;
import com.ibm.common.activitystreams.actions.StylesValue;
import com.ibm.common.activitystreams.actions.UrlTemplate;
/**
*/
public final class Actions {
private Actions() {}
private static final IO io =
IO.makeDefaultPrettyPrint(ActionsModule.instance);
// Set up some common static action handlers...
private static final ASObject httpAction =
httpAction("http://example.org", METHOD_POST)
.auth(
"oauth2",
object()
.set("scopes",
object()
.set(
"scope.key.1",
object().set("description", "foo"))))
.expects(
htmlForm()
.parameter("foo", "http://example.org/FooProperty"))
.expects(
typedPayload("text/json")
.schema("http://foo")
.type("http://schema.org/Foo"))
.returns(typedPayload("text/json"))
.returns(typedPayload("text/html"))
.requires(
"urn:example:some:feature",
"urn:example:some:other:feature")
.prefers(
"urn:example:some:optional-feature")
.target(TARGET_DIALOG)
.get();
private static final ASObject embedAction =
staticEmbedAction(
"text/plain",
"this is a pretty useless handler")
.style(
styles("print")
.set("height", "100px")
.set("width", "100px")
.get(),
styles("screen")
.set("width", "200px")
.set("height", "200px")
.get()
)
.get();
private static final ASObject urlTemplate =
urlTemplate()
.template("http://foo{/path}{?query}")
.parameter("path", "http://example.org/types#string")
.parameter("query", "http://example.org/types#string")
.parameter(
"foo",
parameter()
.required()
.repeated()
.formatInt32()
.minimum(1)
.maximum(3)
.enumVals(1,2,3)
.step(1)
.formatUint32()
.placeholder("(1, 2 or 3)")
)
.get();
private static final ASObject intent =
intentAction()
.mediaType("text/plain")
.url("app://com.example.MoviePlayer")
.get();
/**
* Method main.
* @param args String[]
* @throws Exception
*/
public static void main(String... args) throws Exception {
ByteArrayOutputStream out =
new ByteArrayOutputStream();
ASObject obj =
object()
.action(
"view",
httpAction,
embedAction,
urlTemplate,
intent)
.action(
"share",
"http://example.org/foo")
.get();
io.write(obj,System.out);
System.out.println("\n\n");
io.write(
obj,
out);
obj = io.read(new ByteArrayInputStream(out.toByteArray()));
ActionsValue actions = obj.actions();
for (LinkValue lv : actions.get("view")) {
if (lv instanceof HttpActionHandler) {
HttpActionHandler httpAction = (HttpActionHandler) lv;
System.out.println("Auth: " + httpAction.auth());
System.out.println("Method: " + httpAction.method());
System.out.println("URL: " + httpAction.url());
System.out.println("Target: " + httpAction.target());
System.out.println("Returns: " + httpAction.returns());
System.out.println("Expects: " + httpAction.expects());
System.out.println("Requires: " + httpAction.requires());
System.out.println("Prefers: " + httpAction.prefers());
} else if (lv instanceof EmbedActionHandler) {
EmbedActionHandler embed = (EmbedActionHandler) lv;
for (StylesValue style : embed.styles("print")) {
System.out.println(style.get("height"));
System.out.println(style.get("width"));
}
} else if (lv instanceof UrlTemplate) {
UrlTemplate template = (UrlTemplate) lv;
System.out.println(template.template());
ParametersValue pv = template.parameters();
for (String s : pv) {
TypeValue param = pv.get(s);
if (param.valueType() == ValueType.SIMPLE) {
System.out.println(s + " = " + param.id());
} else {
if (param instanceof Parameter) {
Parameter par = (Parameter) param;
System.out.println(s + " = " + par.id() + ", " + par.required() + ", " + par.format() + ", " + par.enumVals());
} else {
System.out.println(s + " = " + param);
}
}
}
}
}
}
}

View File

@ -0,0 +1,343 @@
package com.ibm.common.activitystreams.actions;
import java.io.Serializable;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.LinkValue;
/**
*/
public abstract class ActionHandler
extends ASObject
implements Serializable {
/**
*/
@SuppressWarnings("unchecked")
public static abstract class Builder<A extends ActionHandler, B extends Builder<A,B>>
extends ASObject.AbstractBuilder<A, B> {
private final Authentication.Builder auth =
Authentication.make();
/**
* Method confirm.
* @return B
*/
public B confirm() {
return confirm(true);
}
/**
* Method confirm.
* @param on boolean
* @return B
*/
public B confirm(boolean on) {
set("confirm", on);
return (B)this;
}
/**
* Method context.
* @param obj ASObject
* @return B
*/
public B context(ASObject obj) {
set("context", obj);
return (B)this;
}
/**
* Method context.
* @param obj Supplier<? extends ASObject>
* @return B
*/
public B context(Supplier<? extends ASObject> obj) {
return context(obj.get());
}
/**
* Method requires.
* @param iri String
* @return B
*/
public B requires(String iri, String... iris) {
requires(LinkValue.SimpleLinkValue.make(iri));
if (iris != null)
for (String i : iris)
requires(i);
return (B)this;
}
/**
* Method requires.
* @param lv LinkValue
* @return B
*/
public B requires(LinkValue lv, LinkValue... lvs) {
link("requires", lv);
if (lvs != null)
for (LinkValue i : lvs)
requires(i);
return (B)this;
}
/**
* Method requires.
* @param lv Supplier<? extends LinkValue>
* @return B
*/
public B requires(Supplier<? extends LinkValue> lv) {
return requires(lv.get());
}
/**
* Method prefers.
* @param iri String
* @return B
*/
public B prefers(String iri, String... iris) {
prefers(LinkValue.SimpleLinkValue.make(iri));
if (iris != null)
for (String i : iris)
prefers(i);
return (B) this;
}
/**
* Method prefers.
* @param lv LinkValue
* @return B
*/
public B prefers(LinkValue lv, LinkValue... lvs) {
link("prefers", lv);
if (lvs != null)
for (LinkValue l : lvs)
prefers(l);
return (B)this;
}
/**
* Method prefers.
* @param lv Supplier<? extends LinkValue>
* @return B
*/
public B prefers(Supplier<? extends LinkValue> lv) {
return prefers(lv.get());
}
/**
* Method expects.
* @param iri String
* @return B
*/
public B expects(String iri, String... iris) {
expects(LinkValue.SimpleLinkValue.make(iri));
if (iris != null)
for (String i : iris)
expects(i);
return (B)this;
}
/**
* Method expects.
* @param tv LinkValue
* @return B
*/
public B expects(LinkValue tv, LinkValue... lvs) {
link("expects", tv);
if (lvs != null)
for (LinkValue lv : lvs)
expects(lv);
return (B)this;
}
/**
* Method expects.
* @param tv Supplier<? extends LinkValue>
* @return B
*/
public B expects(Supplier<? extends LinkValue> tv) {
return expects(tv.get());
}
/**
* Method returns.
* @param iri String
* @return B
*/
public B returns(String iri, String... iris) {
returns(LinkValue.SimpleLinkValue.make(iri));
if (iris != null)
for (String i : iris)
returns(i);
return (B)this;
}
/**
* Method returns.
* @param tv LinkValue
* @return B
*/
public B returns(LinkValue tv, LinkValue... lvs) {
link("returns", tv);
if (lvs != null)
for (LinkValue lv : lvs)
returns(lv);
return (B)this;
}
/**
* Method returns.
* @param tv Supplier<? extends LinkValue>
* @return B
*/
public B returns(Supplier<? extends LinkValue> tv) {
return returns(tv.get());
}
/**
* Method auth.
* @param key String
* @param obj ASObject
* @return B
*/
public B auth(String key, ASObject obj) {
auth.set(key, obj);
return (B)this;
}
/**
* Method auth.
* @param key String
* @param obj Supplier<? extends ASObject>
* @return B
*/
public B auth(String key, Supplier<? extends ASObject> obj) {
return auth(key, obj.get());
}
/**
* Method get.
* @return A
* @see com.google.common.base.Supplier#get()
*/
public A get() {
if (auth.notEmpty())
set("auth", auth.get());
return actualGet();
}
/**
* Method actualGet.
* @return A
*/
protected abstract A actualGet();
}
/**
* Constructor for ActionHandler.
* @param builder Builder<?,?>
*/
protected ActionHandler(Builder<?,?> builder) {
super(builder);
}
/**
* Method confirm.
* @return boolean
*/
public boolean confirm() {
return this.getBoolean("confirm");
}
/**
* Method context.
* @return A
*/
public <A extends ASObject>A context() {
return this.<A>get("context");
}
/**
* Method expects.
* @return Iterable<LinkValue>
*/
public Iterable<LinkValue> expects() {
return this.links("expects");
}
public Iterable<LinkValue> expects(Predicate<? super LinkValue> filter) {
return this.links("expects", filter);
}
/**
* Method requires.
* @return Iterable<LinkValue>
*/
public Iterable<LinkValue> requires() {
return this.links("requires");
}
public Iterable<LinkValue> requires(Predicate<? super LinkValue> filter) {
return this.links("requires", filter);
}
/**
* Method prefers.
* @return Iterable<LinkValue>
*/
public Iterable<LinkValue> prefers() {
return this.links("prefers");
}
public Iterable<LinkValue> prefers(Predicate<? super LinkValue> filter) {
return this.links("prefers", filter);
}
/**
* Method returns.
* @return Iterable<LinkValue>
*/
public Iterable<LinkValue> returns() {
return this.links("returns");
}
public Iterable<LinkValue> returns(Predicate<? super LinkValue> filter) {
return this.links("returns", filter);
}
/**
* Method auth.
* @return Authentication
*/
public Authentication auth() {
return this.<Authentication>get("auth");
}
/**
* Method hasAuth.
* @param key String
* @return boolean
*/
public boolean hasAuth(String key) {
Authentication auth = auth();
return auth != null ?
auth.has(key) : false;
}
/**
* Method auth.
* @param key String
* @return A
*/
@SuppressWarnings("unchecked")
public <A extends ASObject>A auth(String key) {
Authentication auth = auth();
return auth != null ?
(A)auth.get(key) : null;
}
}

View File

@ -0,0 +1,205 @@
package com.ibm.common.activitystreams.actions;
import static com.ibm.common.activitystreams.Makers.object;
import com.ibm.common.activitystreams.ASObject;
/**
*/
public final class ActionMakers {
public static final String TARGET_NONE = "NONE";
public static final String TARGET_DEFAULT = "DEFAULT";
public static final String TARGET_NEW = "NEW";
public static final String TARGET_CURRENT = "CURRENT";
public static final String TARGET_TAB = "TAB";
public static final String TARGET_DIALOG = "DIALOG";
public static final String TARGET_MODALDIALOG = "MODALDIALOG";
public static final String TARGET_FLOAT = "FLOAT";
public static final String TARGET_SIDEBAR = "SIDEBAR";
public static final String METHOD_GET = "GET";
public static final String METHOD_POST = "POST";
public static final String METHOD_PUT = "PUT";
public static final String METHOD_DELETE = "DELETE";
public static final String METHOD_PATCH = "PATCH";
private ActionMakers() {}
/**
* Method application.
* @return ASObject.Builder
*/
public static ASObject.Builder application() {
return object("application");
}
/**
* Method service.
* @return ASObject.Builder
*/
public static ASObject.Builder service() {
return object("service");
}
/**
* Method styles.
* @return StylesValue.Builder
*/
public static StylesValue.Builder styles() {
return StylesValue.make();
}
/**
* Method styles.
* @param media String
* @return StylesValue.Builder
*/
public static StylesValue.Builder styles(String media) {
return styles().media(media);
}
/**
* Method httpAction.
* @return HttpActionHandler.Builder
*/
public static HttpActionHandler.Builder httpAction() {
return HttpActionHandler.makeHttpActionHandler();
}
/**
* Method httpAction.
* @param url String
* @return HttpActionHandler.Builder
*/
public static HttpActionHandler.Builder httpAction(String url) {
return httpAction().url(url);
}
/**
* Method httpAction.
* @param url String
* @param method String
* @return HttpActionHandler.Builder
*/
public static HttpActionHandler.Builder httpAction(
String url,
String method) {
return httpAction()
.url(url)
.method(method);
}
/**
* Method embedAction.
* @return EmbedActionHandler.Builder
*/
public static EmbedActionHandler.Builder embedAction() {
return EmbedActionHandler.makeEmbedActionHandler();
}
/**
* Method embedAction.
* @param url String
* @return EmbedActionHandler.Builder
*/
public static EmbedActionHandler.Builder embedAction(String url) {
return embedAction().url(url);
}
/**
* Method embedAction.
* @param url String
* @param mediaType String
* @return EmbedActionHandler.Builder
*/
public static EmbedActionHandler.Builder embedAction(
String url,
String mediaType) {
return embedAction(url).mediaType(mediaType);
}
/**
* Method staticEmbedAction.
* @param mediaType String
* @param content String
* @return EmbedActionHandler.Builder
*/
public static EmbedActionHandler.Builder staticEmbedAction(
String mediaType,
String content) {
return embedAction().mediaType(mediaType).content(content);
}
/**
* Method intentAction.
* @return IntentActionHandler.Builder
*/
public static IntentActionHandler.Builder intentAction() {
return IntentActionHandler.makeIntentActionHandler();
}
/**
* Method intentAction.
* @param url String
* @return IntentActionHandler.Builder
*/
public static IntentActionHandler.Builder intentAction(String url) {
return intentAction().url(url);
}
/**
* Method htmlForm.
* @return HtmlForm.Builder
*/
public static HtmlForm.Builder htmlForm() {
return HtmlForm.makeHtmlForm();
}
/**
* Method typedPayload.
* @param mediaType String
* @return TypedPayload.Builder
*/
public static TypedPayload.Builder typedPayload(String mediaType) {
return TypedPayload.makeTypedPayload(mediaType);
}
public static TypedPayload.Builder typedPayload() {
return TypedPayload.make();
}
/**
* Method urlTemplate.
* @return UrlTemplate.Builder
*/
public static UrlTemplate.Builder urlTemplate() {
return UrlTemplate.makeUrlTemplate();
}
/**
* Method urlTemplate.
* @param template String
* @return UrlTemplate.Builder
*/
public static UrlTemplate.Builder urlTemplate(String template) {
return urlTemplate().template(template);
}
/**
* Method parameter.
* @return Parameter.Builder
*/
public static Parameter.Builder parameter() {
return Parameter.makeParameter();
}
/**
* Method parameter.
* @param id String
* @return Parameter.Builder
*/
public static Parameter.Builder parameter(String id) {
return parameter().id(id);
}
}

View File

@ -0,0 +1,85 @@
package com.ibm.common.activitystreams.actions;
import java.lang.reflect.Type;
import com.google.common.collect.ImmutableSet;
import com.ibm.common.activitystreams.ASObject.AbstractBuilder;
import com.ibm.common.activitystreams.internal.ASObjectAdapter;
import com.ibm.common.activitystreams.internal.Model;
import com.ibm.common.activitystreams.internal.Schema;
public final class ActionObjectAdapter
extends ASObjectAdapter {
ActionObjectAdapter(Schema schema) {
super(schema);
}
private static final ImmutableSet<Class<?>> knownTypes =
ImmutableSet.<Class<?>>of(
HttpActionHandler.class,
IntentActionHandler.class,
EmbedActionHandler.class,
HtmlForm.class,
UrlTemplate.class,
TypedPayload.class
);
@Override
protected boolean knowsType(Type type) {
if (super.knowsType(type))
return true;
return knownTypes.contains(type);
}
@Override
protected AbstractBuilder<?, ?> builderFor(Type type) {
if (super.knowsType(type))
return super.builderFor(type);
if (type == HttpActionHandler.class)
return ActionMakers.httpAction();
else if (type == IntentActionHandler.class)
return ActionMakers.intentAction();
else if (type == EmbedActionHandler.class)
return ActionMakers.embedAction();
else if (type == HtmlForm.class)
return ActionMakers.htmlForm();
else if (type == UrlTemplate.class)
return ActionMakers.urlTemplate();
else if (type == TypedPayload.class)
return ActionMakers.typedPayload();
else return null;
}
@Override
protected Model modelFor(Type type) {
if (super.knowsType(type))
return super.modelFor(type);
if (type == HttpActionHandler.class)
return schema().forObjectClassOrType(
HttpActionHandler.Builder.class,
"HttpActionHandler");
else if (type == IntentActionHandler.class)
return schema().forObjectClassOrType(
IntentActionHandler.Builder.class,
"IntentActionHandler");
else if (type == EmbedActionHandler.class)
return schema().forObjectClassOrType(
EmbedActionHandler.Builder.class,
"EmbedActionHandler");
else if (type == HtmlForm.class)
return schema().forObjectClassOrType(
HtmlForm.Builder.class,
"HtmlForm");
else if (type == UrlTemplate.class)
return schema().forObjectClassOrType(
UrlTemplate.Builder.class,
"UrlTemplate");
else if (type == TypedPayload.class)
return schema().forObjectClassOrType(
TypedPayload.Builder.class,
"TypedPayload");
else return null;
}
}

View File

@ -0,0 +1,82 @@
package com.ibm.common.activitystreams.actions;
import static com.ibm.common.activitystreams.actions.Adapters.AUTH;
import static com.ibm.common.activitystreams.actions.Adapters.PARAMETERS;
import static com.ibm.common.activitystreams.actions.Adapters.STYLES;
import com.ibm.common.activitystreams.IO.Builder;
import com.ibm.common.activitystreams.internal.Model;
import com.ibm.common.activitystreams.internal.Schema;
import com.ibm.common.activitystreams.util.Module;
public final class ActionsModule
implements Module {
public static final Module instance = new ActionsModule();
@Override
public void apply(Builder builder, Schema schema) {
ActionObjectAdapter base =
new ActionObjectAdapter(schema);
// Register Adapters
builder.hierarchicalAdapter(ActionHandler.class,base)
.hierarchicalAdapter(HttpActionHandler.class,base)
.hierarchicalAdapter(IntentActionHandler.class,base)
.hierarchicalAdapter(EmbedActionHandler.class,base)
.hierarchicalAdapter(HtmlForm.class,base)
.hierarchicalAdapter(UrlTemplate.class,base)
.hierarchicalAdapter(TypedPayload.class,base)
.hierarchicalAdapter(Parameter.class,base)
.hierarchicalAdapter(ParametersValue.class, PARAMETERS)
.hierarchicalAdapter(Authentication.class, AUTH)
.hierarchicalAdapter(StylesValue.class, STYLES);
}
@Override
public void apply(Schema.Builder builder) {
builder.map("HtmlForm", withParameters.template(HtmlForm.class, HtmlForm.Builder.class))
.map("parameter", parameter)
.map("TypedPayload", typedPayload)
.map("UrlTemplate", withParameters.template(UrlTemplate.class, UrlTemplate.Builder.class))
.map("HttpActionHandler", actionHandler.template(HttpActionHandler.class, HttpActionHandler.Builder.class))
.map("IntentActionHandler", actionHandler.template(IntentActionHandler.class, IntentActionHandler.Builder.class))
.map("EmbedActionHandler", actionHandler.template(EmbedActionHandler.class, EmbedActionHandler.Builder.class));
}
public final static Model actionHandler =
Model
.make("object")
.linkValue(
"expects",
"returns",
"requires",
"prefers")
.object("context")
.as("auth", Authentication.class)
.as("style", StylesValue.class)
.get();
public final static Model withParameters =
Model
.make("object")
.as("parameters", ParametersValue.class)
.get();
public final static Model typedPayload =
Model
.make("object")
.linkValue("schema")
.typeValue("type")
.get();
public final static Model parameter =
Model
.make("object")
.typeValue("type")
.type(Parameter.class, Parameter.Builder.class)
.get();
}

View File

@ -0,0 +1,46 @@
package com.ibm.common.activitystreams.actions;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.TypeValue;
import com.ibm.common.activitystreams.actions.StylesValue.Builder;
import com.ibm.common.activitystreams.internal.Adapter;
import com.ibm.common.activitystreams.util.AbstractDictionaryObjectAdapter;
final class Adapters {
private Adapters() {}
static final Adapter<Authentication> AUTH =
new AbstractDictionaryObjectAdapter
<ASObject,
Authentication,
Authentication.Builder>(ASObject.class) {
@Override
protected Authentication.Builder builder() {
return Authentication.make();
}
};
static final Adapter<ParametersValue> PARAMETERS =
new AbstractDictionaryObjectAdapter
<TypeValue,
ParametersValue,
ParametersValue.Builder>(TypeValue.class) {
@Override
protected ParametersValue.Builder builder() {
return ParametersValue.make();
}
};
static final Adapter<StylesValue> STYLES =
new AbstractDictionaryObjectAdapter
<String,
StylesValue,
StylesValue.Builder>(String.class) {
@Override
protected Builder builder() {
return StylesValue.make();
}
};
}

View File

@ -0,0 +1,83 @@
package com.ibm.common.activitystreams.actions;
import java.io.Serializable;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.util.AbstractDictionaryObject;
/**
*/
public final class Authentication
extends AbstractDictionaryObject<ASObject> {
/**
* Method make.
* @return Builder
*/
public static Builder make() {
return new Builder();
}
/**
*/
public static final class Builder
extends AbstractDictionaryObject.AbstractBuilder<
ASObject,Authentication,Builder> {
/**
* Method get.
* @return Authentication
* @see com.google.common.base.Supplier#get()
*/
public Authentication get() {
return new Authentication(this);
}
}
/**
* Constructor for Authentication.
* @param builder Builder
*/
protected Authentication(Builder builder) {
super(builder);
}
/**
* Method get.
* @param key String
* @return A
*/
@SuppressWarnings("unchecked")
public <A extends ASObject>A get(String key) {
return (A)this.getSingle(key);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private ImmutableMap<String,Object> map;
SerializedForm(Authentication obj) {
ImmutableMap.Builder<String,Object> builder =
ImmutableMap.builder();
for (String key : obj)
builder.put(key, obj.get(key));
this.map = builder.build();
}
Object readResolve()
throws java.io.ObjectStreamException {
Authentication.Builder builder =
Authentication.make();
for (Map.Entry<String,Object> entry : map.entrySet())
builder.set(entry.getKey(), (ASObject) entry.getValue());
return builder.get();
}
}
}

View File

@ -0,0 +1,213 @@
package com.ibm.common.activitystreams.actions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.getFirst;
import static com.google.common.collect.Iterables.size;
import java.io.ObjectStreamException;
import java.io.Serializable;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
/**
*/
public class EmbedActionHandler
extends ActionHandler
implements Serializable {
/**
* Method makeEmbedActionHandler.
* @return Builder
*/
public static Builder makeEmbedActionHandler() {
return new Builder();
}
/**
*/
public static final class Builder
extends AbstractBuilder<EmbedActionHandler, Builder> {
public Builder() {
super("EmbedActionHandler");
}
/**
* Method getActual.
* @return EmbedActionHandler
*/
protected EmbedActionHandler getActual() {
return new EmbedActionHandler(this);
}
}
/**
*/
@SuppressWarnings("unchecked")
public static abstract class AbstractBuilder<A extends EmbedActionHandler, B extends AbstractBuilder<A,B>>
extends ActionHandler.Builder<A,B> {
private boolean styleset = false;
private static ImmutableList.Builder<StylesValue> styles =
ImmutableList.builder();
/**
* Constructor for AbstractBuilder.
* @param objectType String
*/
protected AbstractBuilder(String objectType) {
objectType(objectType);
}
/**
* Method target.
* @param target String
* @return B
*/
public B target(String target) {
set("target", target);
return (B)this;
}
/**
* Method style.
* @param style StylesValue
* @return B
*/
public B style(StylesValue style) {
styleset = true;
styles.add(style);
return (B)this;
}
/**
* Method style.
* @param style Supplier<StylesValue>
* @return B
*/
public B style(Supplier<StylesValue> style) {
return style(style.get());
}
/**
* Method style.
* @param styles StylesValue[]
* @return B
*/
public B style(StylesValue... styles) {
for (StylesValue s : styles)
style(s);
return (B)this;
}
/**
* Method style.
* @param styles Supplier<StylesValue>[]
* @return B
*/
public B style(Supplier<StylesValue>... styles) {
for (Supplier<StylesValue> s : styles)
style(s);
return (B)this;
}
/**
* Method actualGet.
* @return A
*/
protected final A actualGet() {
if (styleset) {
ImmutableList<StylesValue> val = styles.build();
if (size(val) == 1) {
set("style", getFirst(val,null));
} else {
set("style", val);
}
}
return getActual();
}
/**
* Method getActual.
* @return A
*/
protected abstract A getActual();
}
/**
* Constructor for EmbedActionHandler.
* @param builder AbstractBuilder<?,?>
*/
protected EmbedActionHandler(AbstractBuilder<?,?> builder) {
super(builder);
}
/**
* Method styles.
* @return Iterable<StylesValue>
*/
@SuppressWarnings("unchecked")
public Iterable<StylesValue> styles() {
Object styles = get("style");
if (styles instanceof StylesValue)
return ImmutableList.<StylesValue>of((StylesValue)styles);
else if (styles instanceof Iterable)
return (Iterable<StylesValue>)styles;
else return ImmutableList.of();
}
/**
* Method styles.
* @param media String
* @return Iterable<StylesValue>
*/
public Iterable<StylesValue> styles(final String media) {
checkNotNull(media);
return styles(new Predicate<StylesValue>() {
public boolean apply(StylesValue style) {
return media.equalsIgnoreCase(style.media());
}
});
}
/**
* Method styles.
* @param matcher Predicate<StylesValue>
* @return Iterable<StylesValue>
*/
public Iterable<StylesValue> styles(Predicate<StylesValue> matcher) {
return filter(styles(), matcher);
}
/**
* Method target.
* @return String
*/
public String target() {
return getString(
"target",
ActionMakers.TARGET_DEFAULT);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<EmbedActionHandler> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(EmbedActionHandler obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected EmbedActionHandler.Builder builder() {
return ActionMakers.embedAction();
}
}
}

View File

@ -0,0 +1,161 @@
package com.ibm.common.activitystreams.actions;
import static com.ibm.common.activitystreams.Makers.object;
import static com.ibm.common.activitystreams.Makers.type;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.TypeValue;
/**
*/
public final class HtmlForm
extends ASObject {
/**
* Method makeHtmlForm.
* @return Builder
*/
public static Builder makeHtmlForm() {
return new Builder();
}
/**
*/
public static final class Builder
extends ASObject.AbstractBuilder<HtmlForm, Builder> {
private final ParametersValue.Builder params =
ParametersValue.make();
private Builder() {
objectType("HtmlForm");
mediaType("application/x-www-form-urlencoded");
}
/**
* Method parameter.
* @param name String
* @param iri String
* @return Builder
*/
public Builder parameter(
String name,
String iri) {
params.set(name, type(iri));
return this;
}
/**
* Method parameter.
* @param name String
* @param iri String
* @param required boolean
* @return Builder
*/
public Builder parameter(
String name,
String iri,
boolean required) {
return parameter(
name,
object()
.id(iri)
.set("required", required));
}
/**
* Method parameter.
* @param name String
* @param iri String
* @param required boolean
* @param value Object
* @return Builder
*/
public Builder parameter(
String name,
String iri,
boolean required,
Object value) {
return parameter(
name,
object()
.id(iri)
.set("required", required)
.set("value", value));
}
/**
* Method parameter.
* @param name String
* @param lv TypeValue
* @return Builder
*/
public Builder parameter(
String name,
TypeValue lv) {
params.set(name, lv);
return this;
}
/**
* Method parameter.
* @param name String
* @param lv Supplier<? extends TypeValue>
* @return Builder
*/
public Builder parameter(
String name,
Supplier<? extends TypeValue> lv) {
return parameter(name, lv.get());
}
/**
* Method get.
* @return HtmlForm
* @see com.google.common.base.Supplier#get()
*/
public HtmlForm get() {
if (params.notEmpty())
set("parameters", params.get());
return new HtmlForm(this);
}
}
/**
* Constructor for HtmlForm.
* @param builder Builder
*/
private HtmlForm(Builder builder) {
super(builder);
}
/**
* Method parameters.
* @return ParametersValue
*/
public ParametersValue parameters() {
return this.<ParametersValue>get("parameters");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<HtmlForm> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(HtmlForm obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected HtmlForm.Builder builder() {
return ActionMakers.htmlForm();
}
}
}

View File

@ -0,0 +1,116 @@
package com.ibm.common.activitystreams.actions;
import java.io.ObjectStreamException;
/**
*/
public class HttpActionHandler
extends ActionHandler {
/**
* Method makeHttpActionHandler.
* @return Builder
*/
public static Builder makeHttpActionHandler() {
return new Builder();
}
/**
*/
public static final class Builder
extends AbstractBuilder<HttpActionHandler, Builder> {
public Builder() {
super("HttpActionHandler");
}
/**
* Method actualGet.
* @return HttpActionHandler
*/
protected HttpActionHandler actualGet() {
return new HttpActionHandler(this);
}
}
/**
*/
@SuppressWarnings("unchecked")
public static abstract class AbstractBuilder
<A extends HttpActionHandler, B extends AbstractBuilder<A,B>>
extends ActionHandler.Builder<A,B> {
/**
* Constructor for AbstractBuilder.
* @param objectType String
*/
protected AbstractBuilder(String objectType) {
objectType(objectType);
}
/**
* Method method.
* @param method String
* @return B
*/
public B method(String method) {
set("method", method);
return (B)this;
}
/**
* Method target.
* @param target String
* @return B
*/
public B target(String target) {
set("target", target);
return (B)this;
}
}
/**
* Constructor for HttpActionHandler.
* @param builder AbstractBuilder<?,?>
*/
protected HttpActionHandler(AbstractBuilder<?,?> builder) {
super(builder);
}
/**
* Method method.
* @return String
*/
public String method() {
return this.getString("method");
}
/**
* Method target.
* @return String
*/
public String target() {
return has("target") ?
this.<String>get("target") :
ActionMakers.TARGET_DEFAULT;
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<HttpActionHandler> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(HttpActionHandler obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected HttpActionHandler.Builder builder() {
return ActionMakers.httpAction();
}
}
}

View File

@ -0,0 +1,77 @@
package com.ibm.common.activitystreams.actions;
import java.io.ObjectStreamException;
/**
*/
public class IntentActionHandler
extends ActionHandler {
/**
* Method makeIntentActionHandler.
* @return Builder
*/
public static Builder makeIntentActionHandler() {
return new Builder();
}
/**
*/
public static final class Builder
extends AbstractBuilder<IntentActionHandler, Builder> {
public Builder() {
super("IntentActionHandler");
}
/**
* Method actualGet.
* @return IntentActionHandler
*/
protected IntentActionHandler actualGet() {
return new IntentActionHandler(this);
}
}
/**
*/
public static abstract class AbstractBuilder
<A extends IntentActionHandler, B extends AbstractBuilder<A,B>>
extends ActionHandler.Builder<A,B> {
/**
* Constructor for AbstractBuilder.
* @param objectType String
*/
protected AbstractBuilder(String objectType) {
objectType(objectType);
}
}
/**
* Constructor for IntentActionHandler.
* @param builder AbstractBuilder<?,?>
*/
protected IntentActionHandler(AbstractBuilder<?,?> builder) {
super(builder);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<IntentActionHandler> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(IntentActionHandler obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected IntentActionHandler.Builder builder() {
return ActionMakers.intentAction();
}
}
}

View File

@ -0,0 +1,949 @@
package com.ibm.common.activitystreams.actions;
import java.io.ObjectStreamException;
import java.util.regex.Pattern;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.NLV;
import com.ibm.common.activitystreams.TypeValue;
/**
*/
public class Parameter
extends ASObject {
/**
*/
public static enum Format {
OTHER(null),
BOOLEAN("boolean"),
INT32("int32"),
INT64("int64"),
UINT32("uint32"),
UINT64("uint64"),
DOUBLE("double"),
FLOAT("float"),
BYTE("byte"),
DATE("date"),
DATETIME("date-time"),
DURATION("duration"),
LANG("lang"),
URI("uri"),
IRI("iri")
;
private final String label;
/**
* Constructor for Format.
* @param label String
*/
Format(String label) {
this.label = label;
}
/**
* Method select.
* @param label String
* @return Format
*/
private static Format select(String label) {
try {
if (label == null)
return Format.OTHER;
label = label.toUpperCase().replaceAll("-", "");
return valueOf(label);
} catch (Throwable t) {
return Format.OTHER;
}
}
}
/**
* Method makeParameter.
* @return Builder
*/
public static Builder makeParameter() {
return new Builder();
}
/**
*/
public static final class Builder
extends AbstractBuilder<Parameter,Builder> {
/**
* Method get.
* @return Parameter
* @see com.google.common.base.Supplier#get()
*/
public Parameter get() {
return new Parameter(this);
}
}
/**
*/
public static abstract class AbstractBuilder<P extends Parameter, B extends AbstractBuilder<P,B>>
extends ASObject.AbstractBuilder<P,B> {
protected AbstractBuilder() {
objectType("parameter");
}
/**
* Method placeholder.
* @param val String
* @return B
*/
public B placeholder(String val) {
return this._nlv("placeholder", val);
}
/**
* Method placeholder.
* @param nlv NLV
* @return B
*/
public B placeholder(NLV nlv) {
return this._nlv("placeholder", nlv);
}
/**
* Method placeholder.
* @param nlv Supplier<? extends NLV>
* @return B
*/
public B placeholder(Supplier<? extends NLV> nlv) {
return this._nlv("placeholder", nlv);
}
/**
* Method placeholder.
* @param lang String
* @param val String
* @return B
*/
public B placeholder(String lang, String val) {
return this._nlv("placeholder", lang, val);
}
/**
* Method type.
* @param iri String
* @return B
*/
public B type(String iri) {
return type(TypeValue.SimpleTypeValue.make(iri));
}
/**
* Method type.
* @param tv TypeValue
* @return B
*/
public B type(TypeValue tv) {
return set("type", tv);
}
/**
* Method type.
* @param tv Supplier<? extends TypeValue>
* @return B
*/
public B type(Supplier<? extends TypeValue> tv) {
return type(tv.get());
}
/**
* Method required.
* @param on boolean
* @return B
*/
public B required(boolean on) {
return set("required", on);
}
/**
* Method repeated.
* @param on boolean
* @return B
*/
public B repeated(boolean on) {
return set("repeated", on);
}
/**
* Method required.
* @return B
*/
public B required() {
return required(true);
}
/**
* Method repeated.
* @return B
*/
public B repeated() {
return repeated(true);
}
/**
* Method value.
* @param value Object
* @return B
*/
public B value(Object value) {
return set("value", value);
}
/**
* Method defaultValue.
* @param value Object
* @return B
*/
public B defaultValue(Object value) {
return set("default", value);
}
/**
* Method format.
* @param format Format
* @return B
*/
@SuppressWarnings("unchecked")
public B format(Format format) {
if (format == Format.OTHER)
return (B)this;
return format(format.label);
}
/**
* Method formatInt32.
* @return B
*/
public B formatInt32() {
return format(Format.INT32);
}
/**
* Method formatInt64.
* @return B
*/
public B formatInt64() {
return format(Format.INT64);
}
/**
* Method formatUint32.
* @return B
*/
public B formatUint32() {
return format(Format.UINT32);
}
/**
* Method formatUint64.
* @return B
*/
public B formatUint64() {
return format(Format.UINT64);
}
/**
* Method formatDouble.
* @return B
*/
public B formatDouble() {
return format(Format.DOUBLE);
}
/**
* Method formatFloat.
* @return B
*/
public B formatFloat() {
return format(Format.FLOAT);
}
/**
* Method formatByte.
* @return B
*/
public B formatByte() {
return format(Format.BYTE);
}
/**
* Method formatDate.
* @return B
*/
public B formatDate() {
return format(Format.DATE);
}
/**
* Method formatDateTime.
* @return B
*/
public B formatDateTime() {
return format(Format.DATETIME);
}
/**
* Method formatDuration.
* @return B
*/
public B formatDuration() {
return format(Format.DURATION);
}
/**
* Method formatLang.
* @return B
*/
public B formatLang() {
return format(Format.LANG);
}
/**
* Method formatUri.
* @return B
*/
public B formatUri() {
return format(Format.URI);
}
/**
* Method formatIri.
* @return B
*/
public B formatIri() {
return format(Format.IRI);
}
/**
* Method format.
* @param format String
* @return B
*/
public B format(String format) {
return set("format", format);
}
/**
* Method pattern.
* @param pattern Pattern
* @return B
*/
public B pattern(Pattern pattern) {
return pattern(pattern.pattern());
}
/**
* Method pattern.
* @param pattern String
* @return B
*/
public B pattern(String pattern) {
return set("pattern", pattern);
}
/**
* Method minimum.
* @param min String
* @return B
*/
public B minimum(String min) {
return set("minimum", min);
}
/**
* Method maximum.
* @param max String
* @return B
*/
public B maximum(String max) {
return set("maximum", max);
}
/**
* Method minimum.
* @param min int
* @return B
*/
public B minimum(int min) {
return set("minimum", min);
}
/**
* Method maximum.
* @param max int
* @return B
*/
public B maximum(int max) {
return set("maximum", max);
}
/**
* Method minimum.
* @param min long
* @return B
*/
public B minimum(long min) {
return set("minimum", min);
}
/**
* Method maximum.
* @param max long
* @return B
*/
public B maximum(long max) {
return set("maximum", max);
}
/**
* Method minimum.
* @param min short
* @return B
*/
public B minimum(short min) {
return set("minimum", min);
}
/**
* Method maximum.
* @param max short
* @return B
*/
public B maximum(short max) {
return set("maximum", max);
}
/**
* Method minimum.
* @param min double
* @return B
*/
public B minimum(double min) {
return set("minimum", min);
}
/**
* Method maximum.
* @param max double
* @return B
*/
public B maximum(double max) {
return set("maximum", max);
}
/**
* Method minimum.
* @param min float
* @return B
*/
public B minimum(float min) {
return set("minimum", min);
}
/**
* Method maximum.
* @param max float
* @return B
*/
public B maximum(float max) {
return set("maximum", max);
}
/**
* Method step.
* @param step int
* @return B
*/
public B step(int step) {
return set("step", step);
}
/**
* Method step.
* @param step long
* @return B
*/
public B step(long step) {
return set("step", step);
}
/**
* Method step.
* @param step short
* @return B
*/
public B step(short step) {
return set("step", step);
}
/**
* Method step.
* @param step double
* @return B
*/
public B step(double step) {
return set("step", step);
}
/**
* Method step.
* @param step float
* @return B
*/
public B step(float step) {
return set("step", step);
}
/**
* Method enumVals.
* @param vals Object[]
* @return B
*/
public B enumVals(Object... vals) {
return set("enum", ImmutableList.copyOf(vals));
}
}
/**
* Constructor for Parameter.
* @param builder Builder
*/
protected Parameter(Builder builder) {
super(builder);
}
/**
* Method required.
* @return boolean
*/
public boolean required() {
return getBoolean("required");
}
/**
* Method repeated.
* @return boolean
*/
public boolean repeated() {
return getBoolean("repeated");
}
/**
* Method value.
* @return O
*/
public <O>O value() {
return this.<O>get("value");
}
/**
* Method value.
* @param defaultValue O
* @return O
*/
public <O>O value(O defaultValue) {
return this.<O>get("value", defaultValue);
}
/**
* Method defaultValue.
* @return O
*/
public <O>O defaultValue() {
return this.<O>get("default");
}
/**
* Method defaultValue.
* @param defaultValue O
* @return O
*/
public <O>O defaultValue(O defaultValue) {
return this.<O>get("default", defaultValue);
}
/**
* Method formatString.
* @return String
*/
public String formatString() {
return getString("format");
}
/**
* Method format.
* @return Format
*/
public Format format() {
return Format.select(getString("format"));
}
/**
* Method pattern.
* @return String
*/
public String pattern() {
return getString("pattern");
}
/**
* Method maximum.
* @return String
*/
public String maximum() {
return getString("maximum");
}
/**
* Method minimum.
* @return String
*/
public String minimum() {
return getString("minimum");
}
/**
* Method maximumInt.
* @return int
*/
public int maximumInt() {
return getInt("maximum");
}
/**
* Method minimumInt.
* @return int
*/
public int minimumInt() {
return getInt("minimum");
}
/**
* Method maximumLong.
* @return long
*/
public long maximumLong() {
return getLong("maximum");
}
/**
* Method minimumLong.
* @return long
*/
public long minimumLong() {
return getLong("minimum");
}
/**
* Method maximumShort.
* @return short
*/
public short maximumShort() {
return getShort("maximum");
}
/**
* Method minimumShort.
* @return short
*/
public short minimumShort() {
return getShort("minimum");
}
/**
* Method maximumDouble.
* @return double
*/
public double maximumDouble() {
return getDouble("maximum");
}
/**
* Method minimumDouble.
* @return double
*/
public double minimumDouble() {
return getDouble("minimum");
}
/**
* Method maximumFloat.
* @return float
*/
public float maximumFloat() {
return getFloat("maximum");
}
/**
* Method minimumFloat.
* @return float
*/
public float minimumFloat() {
return getFloat("minimum");
}
/**
* Method maximum.
* @param defaultValue String
* @return String
*/
public String maximum(String defaultValue) {
return getString("maximum", defaultValue);
}
/**
* Method minimum.
* @param defaultValue String
* @return String
*/
public String minimum(String defaultValue) {
return getString("minimum", defaultValue);
}
/**
* Method maximumInt.
* @param defaultValue int
* @return int
*/
public int maximumInt(int defaultValue) {
return getInt("maximum", defaultValue);
}
/**
* Method minimumInt.
* @param defaultValue int
* @return int
*/
public int minimumInt(int defaultValue) {
return getInt("minimum", defaultValue);
}
/**
* Method maximumLong.
* @param defaultValue long
* @return long
*/
public long maximumLong(long defaultValue) {
return getLong("maximum", defaultValue);
}
/**
* Method minimumLong.
* @param defaultValue long
* @return long
*/
public long minimumLong(long defaultValue) {
return getLong("minimum", defaultValue);
}
/**
* Method maximumShort.
* @param defaultValue short
* @return short
*/
public short maximumShort(short defaultValue) {
return getShort("maximum", defaultValue);
}
/**
* Method minimumShort.
* @param defaultValue short
* @return short
*/
public short minimumShort(short defaultValue) {
return getShort("minimum", defaultValue);
}
/**
* Method maximumDouble.
* @param defaultValue double
* @return double
*/
public double maximumDouble(double defaultValue) {
return getDouble("maximum", defaultValue);
}
/**
* Method minimumDouble.
* @param defaultValue double
* @return double
*/
public double minimumDouble(double defaultValue) {
return getDouble("minimum", defaultValue);
}
/**
* Method maximumFloat.
* @param defaultValue float
* @return float
*/
public float maximumFloat(float defaultValue) {
return getFloat("maximum", defaultValue);
}
/**
* Method minimumFloat.
* @param defaultValue float
* @return float
*/
public float minimumFloat(float defaultValue) {
return getFloat("minimum", defaultValue);
}
/**
* Method stepInt.
* @return int
*/
public int stepInt() {
return getInt("step");
}
/**
* Method stepInt.
* @param defaultValue int
* @return int
*/
public int stepInt(int defaultValue) {
return getInt("step", defaultValue);
}
/**
* Method stepLong.
* @return long
*/
public long stepLong() {
return getLong("step");
}
/**
* Method getLong.
* @param defaultValue long
* @return long
*/
public long getLong(long defaultValue) {
return getLong("step", defaultValue);
}
/**
* Method stepShort.
* @return short
*/
public short stepShort() {
return getShort("step");
}
/**
* Method stepShort.
* @param defaultValue short
* @return short
*/
public short stepShort(short defaultValue) {
return getShort("step", defaultValue);
}
/**
* Method stepDouble.
* @return double
*/
public double stepDouble() {
return getDouble("step");
}
/**
* Method stepDouble.
* @param defaultValue double
* @return double
*/
public double stepDouble(double defaultValue) {
return getDouble("step", defaultValue);
}
/**
* Method stepFloat.
* @return float
*/
public float stepFloat() {
return getFloat("step");
}
/**
* Method stepFloat.
* @param defaultValue float
* @return float
*/
public float stepFloat(float defaultValue) {
return getFloat("step", defaultValue);
}
/**
* Method enumVals.
* @return Iterable<Object>
*/
public Iterable<Object> enumVals() {
return this.<Iterable<Object>>get("enum");
}
/**
* Method type.
* @return T
*/
public <T extends TypeValue>T type() {
return this.<T>get("type");
}
/**
* Method placeholder.
* @return NLV
*/
public NLV placeholder() {
return this.<NLV>get("placeholder");
}
/**
* Method placeholderString.
* @return String
*/
public String placeholderString() {
return _nlv("placeholder");
}
/**
* Method placeholderString.
* @param lang String
* @return String
*/
public String placeholderString(String lang) {
return _nlv("placeholder", lang);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Parameter> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Parameter obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Parameter.Builder builder() {
return ActionMakers.parameter();
}
}
}

View File

@ -0,0 +1,152 @@
package com.ibm.common.activitystreams.actions;
import java.io.Serializable;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.TypeValue;
import com.ibm.common.activitystreams.ValueType;
import com.ibm.common.activitystreams.util.AbstractDictionaryObject;
/**
* The value of the "parameters" property...
* @author james
* @version $Revision: 1.0 $
*/
public final class ParametersValue
extends AbstractDictionaryObject<TypeValue>
implements Serializable {
/**
* Method make.
* @return Builder */
public static Builder make() {
return new Builder();
}
/**
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
extends AbstractDictionaryObject.AbstractBuilder
<TypeValue,ParametersValue,Builder> {
/**
* Method set.
* @param param String
* @param iri String
* @return Builder */
public Builder set(String param, String iri) {
return super.set(
param,
TypeValue.SimpleTypeValue.make(iri));
}
/**
* Method get.
* @return ParametersValue * @see com.google.common.base.Supplier#get() */
public ParametersValue get() {
return new ParametersValue(this);
}
}
/**
* Constructor for ParametersValue.
* @param builder Builder
*/
ParametersValue(Builder builder) {
super(builder);
}
/**
* Method get.
* @param param String
* @return TypeValue */
@SuppressWarnings("unchecked")
public <T extends TypeValue>T get(String param) {
return (T)super.getSingle(param);
}
/**
* Method id.
* @param param String
* @return String
*/
public String id(String param) {
TypeValue tv = get(param);
return tv != null ? tv.id() : null;
}
/**
* Method required.
* @param param String
* @return boolean
*/
public boolean required(String param) {
TypeValue tv = get(param);
if (tv == null)
return false;
if (tv.valueType() == ValueType.SIMPLE)
return true;
ASObject obj = (ASObject) tv;
return obj.getBoolean("required", true);
}
/**
* Method value.
* @param param String
* @param defaultValue O
* @return O
*/
public <O>O value(String param, O defaultValue) {
TypeValue tv = get(param);
if (tv == null || tv.valueType() == ValueType.SIMPLE)
return defaultValue;
ASObject obj = (ASObject) tv;
return obj.<O>get("value", defaultValue);
}
/**
* Method value.
* @param param String
* @return O
*/
public <O>O value(String param) {
return value(param,null);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private ImmutableMap<String,Object> map;
SerializedForm(ParametersValue obj) {
ImmutableMap.Builder<String,Object> builder =
ImmutableMap.builder();
for (String key : obj)
builder.put(key, obj.get(key));
this.map = builder.build();
}
Object readResolve()
throws java.io.ObjectStreamException {
ParametersValue.Builder builder =
ParametersValue.make();
for (Map.Entry<String,Object> entry : map.entrySet())
builder.set(entry.getKey(), (TypeValue) entry.getValue());
return builder.get();
}
}
}

View File

@ -0,0 +1,131 @@
package com.ibm.common.activitystreams.actions;
import static com.google.common.base.Preconditions.checkArgument;
import java.io.Serializable;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.ibm.common.activitystreams.TypeValue;
import com.ibm.common.activitystreams.util.AbstractDictionaryObject;
/**
* The value of the "parameters" property...
* @author james
* @version $Revision: 1.0 $
*/
public final class StylesValue
extends AbstractDictionaryObject<String>
implements Serializable {
/**
* Method make.
* @return Builder */
public static Builder make() {
return new Builder();
}
/**
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
extends AbstractDictionaryObject.AbstractBuilder
<String, StylesValue, Builder> {
/**
* Method media.
* @param query String
* @return Builder
*/
public Builder media(String query) {
return super.set("media", query);
}
/**
* Method set.
* @param name String
* @param value String
* @return Builder */
public Builder set(String name, String value) {
checkArgument(!name.equalsIgnoreCase("query"));
return super.set(name, value);
}
/**
* Method get.
* @return ParametersValue * @see com.google.common.base.Supplier#get() */
public StylesValue get() {
return new StylesValue(this);
}
}
/**
* Constructor for ParametersValue.
* @param builder Builder
*/
StylesValue(Builder builder) {
super(builder);
}
/**
* Method media.
* @return String
*/
public String media() {
return getSingle("media");
}
/**
* Method get.
* @param key String
* @return String
*/
public String get(String key) {
return super.getSingle(key);
}
/**
* Method get.
* @param key String
* @param defaultValue String
* @return String
*/
public String get(String key, String defaultValue) {
return super.getSingle(key, defaultValue);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private ImmutableMap<String,String> map;
SerializedForm(StylesValue obj) {
ImmutableMap.Builder<String,String> builder =
ImmutableMap.builder();
for (String key : obj)
builder.put(key, obj.get(key));
this.map = builder.build();
}
Object readResolve()
throws java.io.ObjectStreamException {
StylesValue.Builder builder =
StylesValue.make();
for (Map.Entry<String,String> entry : map.entrySet())
builder.set(entry.getKey(), entry.getValue());
return builder.get();
}
}
}

View File

@ -0,0 +1,160 @@
package com.ibm.common.activitystreams.actions;
import java.io.ObjectStreamException;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.net.MediaType;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.TypeValue;
/**
*/
public final class TypedPayload
extends ASObject {
/**
* Method makeTypedPayload.
* @param mediaType MediaType
* @return Builder
*/
public static Builder makeTypedPayload(MediaType mediaType) {
return new Builder().mediaType(mediaType);
}
/**
* Method makeTypedPayload.
* @param mediaType String
* @return Builder
*/
public static Builder makeTypedPayload(String mediaType) {
return new Builder().mediaType(mediaType);
}
public static Builder make() {
return new Builder();
}
/**
*/
public static final class Builder
extends ASObject.AbstractBuilder<TypedPayload, Builder> {
private Builder() {
objectType("TypedPayload");
}
/**
* Method schema.
* @param iri String
* @return Builder
*/
public Builder schema(String iri) {
return schema(LinkValue.SimpleLinkValue.make(iri));
}
/**
* Method schema.
* @param lv LinkValue
* @return Builder
*/
public Builder schema(LinkValue lv) {
return link("schema", lv);
}
/**
* Method schema.
* @param lv Supplier<? extends LinkValue>
* @return Builder
*/
public Builder schema(Supplier<? extends LinkValue> lv) {
return schema(lv.get());
}
/**
* Method type.
* @param iri String
* @return Builder
*/
public Builder type(String iri) {
return type(TypeValue.SimpleTypeValue.make(iri));
}
/**
* Method type.
* @param tv TypeValue
* @return Builder
*/
public Builder type(TypeValue tv) {
return set("type", tv);
}
/**
* Method type.
* @param tv Supplier<? extends TypeValue>
* @return Builder
*/
public Builder type(Supplier<? extends TypeValue> tv) {
return type(tv.get());
}
/**
* Method get.
* @return TypedPayload
* @see com.google.common.base.Supplier#get()
*/
public TypedPayload get() {
return new TypedPayload(this);
}
}
/**
* Constructor for TypedPayload.
* @param builder Builder
*/
private TypedPayload(Builder builder) {
super(builder);
}
/**
* Method schema.
* @return L
*/
public Iterable<LinkValue> schema() {
return this.links("schema");
}
public Iterable<LinkValue> schema(Predicate<? super LinkValue> filter) {
return this.links("schema", filter);
}
/**
* Method type.
* @return TypeValue
*/
public TypeValue type() {
return this.<TypeValue>get("type");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<TypedPayload> {
private static final long serialVersionUID = -2060301713159936285L;
private String mediaType;
protected SerializedForm(TypedPayload obj) {
super(obj);
this.mediaType = obj.mediaType().toString();
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected TypedPayload.Builder builder() {
return ActionMakers.typedPayload(mediaType);
}
}
}

View File

@ -0,0 +1,176 @@
package com.ibm.common.activitystreams.actions;
import static com.ibm.common.activitystreams.Makers.type;
import static com.ibm.common.activitystreams.Makers.object;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.TypeValue;
/**
*/
public final class UrlTemplate
extends ASObject {
/**
* Method makeUrlTemplate.
* @return Builder
*/
public static Builder makeUrlTemplate() {
return new Builder();
}
/**
*/
public static final class Builder
extends ASObject.AbstractBuilder<UrlTemplate, Builder> {
private final ParametersValue.Builder params =
ParametersValue.make();
private Builder() {
objectType("UrlTemplate");
}
/**
* Method template.
* @param template String
* @return Builder
*/
public Builder template(String template) {
set("template", template);
return this;
}
/**
* Method parameter.
* @param name String
* @param iri String
* @return Builder
*/
public Builder parameter(String name, String iri) {
params.set(name, type(iri));
return this;
}
/**
* Method parameter.
* @param name String
* @param iri String
* @param required boolean
* @return Builder
*/
public Builder parameter(
String name,
String iri,
boolean required) {
return parameter(
name,
object()
.id(iri)
.set("required", required));
}
/**
* Method parameter.
* @param name String
* @param iri String
* @param required boolean
* @param value Object
* @return Builder
*/
public Builder parameter(
String name,
String iri,
boolean required,
Object value) {
return parameter(
name,
object()
.id(iri)
.set("required", required)
.set("value", value));
}
/**
* Method parameter.
* @param name String
* @param lv TypeValue
* @return Builder
*/
public Builder parameter(
String name,
TypeValue lv) {
params.set(name, lv);
return this;
}
/**
* Method parameter.
* @param name String
* @param lv Supplier<? extends TypeValue>
* @return Builder
*/
public Builder parameter(
String name,
Supplier<? extends TypeValue> lv) {
return parameter(name, lv.get());
}
/**
* Method get.
* @return UrlTemplate
* @see com.google.common.base.Supplier#get()
*/
public UrlTemplate get() {
if (params.notEmpty())
set("parameters", params.get());
return new UrlTemplate(this);
}
}
/**
* Constructor for UrlTemplate.
* @param builder Builder
*/
private UrlTemplate(Builder builder) {
super(builder);
}
/**
* Method parameters.
* @return ParametersValue
*/
public ParametersValue parameters() {
return this.<ParametersValue>get("parameters");
}
/**
* Method template.
* @return String
*/
public String template() {
return this.getString("template");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<UrlTemplate> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(UrlTemplate obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected UrlTemplate.Builder builder() {
return ActionMakers.urlTemplate();
}
}
}

17
assembly/assembly.xml Normal file
View File

@ -0,0 +1,17 @@
<assembly>
<id>bin</id>
<formats>
<format>tar.gz</format>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory></outputDirectory>
<includes>
<include>*</include>
</includes>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</assembly>

49
assembly/pom.xml Normal file
View File

@ -0,0 +1,49 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>assembly</artifactId>
<name>Activity Streams 2.0 - Assembly</name>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-actions</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-geo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-legacy</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>

4
core/TODO.md Normal file
View File

@ -0,0 +1,4 @@
# Development Todo's
1. Migrate from GSON to Jackson for JSON parsing
2. Improve Schema/PropertyMap implementation

131
core/pom.xml Executable file
View File

@ -0,0 +1,131 @@
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>activitystreams-core</artifactId>
<packaging>jar</packaging>
<name>Activity Streams 2.0 - Core</name>
<url>http://github.org/opensocial/activitystreams</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<charset>UTF-8</charset>
<additionalparam>-XDignore.symbol.file</additionalparam>
<show>public</show>
<links>
<link>http://www.joda.org/joda-time/apidocs</link>
<link>http://docs.guava-libraries.googlecode.com/git-history/v16.0.1/javadoc/</link>
</links>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Export-Package>com.ibm.common.activitystreams.*</Export-Package>
<Import-Package>
com.google.gson.*,
com.google.common.*,
org.joda.time.*
</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,71 @@
package com.ibm.common.activitystreams.examples;
import static com.ibm.common.activitystreams.IO.makeDefaultPrettyPrint;
import static com.ibm.common.activitystreams.Makers.activity;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.IO;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class Simple {
// The IO object handles all of the reading and writing of the object
private static final IO io = makeDefaultPrettyPrint();
private Simple() {}
/**
* Method main.
* @param args String[]
* @throws Exception */
public static void main(String... args) throws Exception {
// Demonstrates the creation and parsing of a simple Activity Object
// Create the Activity... The API uses a Fluent Generator pattern
Activity activity =
activity()
.verb("post")
.actor("acct:joe@example.org")
.object("http://example.net/posts/1")
.get();
// The Activity object is immutable...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// let's write it out to our outputstream
ByteArrayOutputStream out =
new ByteArrayOutputStream();
activity.writeTo(out, io);
// now let's parse it back in
ByteArrayInputStream in =
new ByteArrayInputStream(
out.toByteArray());
activity = io.readAsActivity(in);
// We get back the same thing...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// If you want to see what was serialized,
// simply write out to stdout...
activity.writeTo(System.out, io);
}
}

View File

@ -0,0 +1,83 @@
package com.ibm.common.activitystreams.examples;
/**
* The Makers class includes a bunch of static generator
* methods that are easiest to use when imported statically
*/
import static com.ibm.common.activitystreams.IO.makeDefaultPrettyPrint;
import static com.ibm.common.activitystreams.Makers.activity;
import static com.ibm.common.activitystreams.Makers.object;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.IO;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class Simple2 {
// The IO object handles all of the reading and writing of the object
private static final IO io = makeDefaultPrettyPrint();
private Simple2() {}
/**
* Method main.
* @param args String[]
* @throws Exception */
public static void main(String... args) throws Exception {
// Demonstrates the creation and parsing of a simple Activity Object
// (we'll use this to store the output...)
ByteArrayOutputStream out =
new ByteArrayOutputStream();
// Create the Activity... The API uses a Fluent Generator pattern
Activity activity =
activity()
.verb("post")
.actor(
object("person")
.id("acct:joe@example.com")
.displayName("Joe Smith")
)
.object(
object("note")
.id("http://example.net/posts/1")
.title("This is the title"))
.get();
// The Activity object is immutable...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// let's write it out to our outputstream
activity.writeTo(out, io);
// now let's parse it back in
ByteArrayInputStream in =
new ByteArrayInputStream(
out.toByteArray());
activity = io.readAsActivity(in);
// We get back the same thing...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// If you want to see what was serialized,
// simply write out to stdout...
activity.writeTo(System.out, io);
}
}

View File

@ -0,0 +1,89 @@
package com.ibm.common.activitystreams.examples;
/**
* The Makers class includes a bunch of static generator
* methods that are easiest to use when imported statically
*/
import static com.ibm.common.activitystreams.IO.makeDefaultPrettyPrint;
import static com.ibm.common.activitystreams.Makers.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.IO;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class Simple3 {
// The IO object handles all of the reading and writing of the object
private static final IO io = makeDefaultPrettyPrint();
private Simple3() {}
/**
* Method main.
* @param args String[]
* @throws Exception */
public static void main(String... args) throws Exception {
// Demonstrates the creation and parsing of a simple Activity Object
// (we'll use this to store the output...)
ByteArrayOutputStream out =
new ByteArrayOutputStream();
// Create the Activity... The API uses a Fluent Generator pattern
Activity activity =
activity()
.verb("post")
.actor(
object()
.objectType(
object()
.id("http://schema.example.net/Person")
.displayName("Person")
.alias("person"))
.id("acct:joe@example.com")
.displayName("Joe Smith")
)
.object(
object("note")
.id("http://example.net/posts/1")
.title(
nlv()
.set("en", "This is the title")
.set("fr", "C'est le titre"))
)
.get();
// The Activity object is immutable...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// let's write it out to our outputstream
activity.writeTo(out, io);
// now let's parse it back in
ByteArrayInputStream in =
new ByteArrayInputStream(
out.toByteArray());
activity = io.readAsActivity(in);
// We get back the same thing...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// If you want to see what was serialized,
// simply write out to stdout...
activity.writeTo(System.out, io);
}
}

View File

@ -0,0 +1,101 @@
package com.ibm.common.activitystreams.examples;
/**
* The Makers class includes a bunch of static generator
* methods that are easiest to use when imported statically
*/
import static com.ibm.common.activitystreams.Activity.Audience.CC;
import static com.ibm.common.activitystreams.Activity.Audience.TO;
import static com.ibm.common.activitystreams.Makers.activity;
import static com.ibm.common.activitystreams.Makers.nlv;
import static com.ibm.common.activitystreams.Makers.object;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.IO;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class Simple4 {
private Simple4() {}
/**
* Method main.
* @param args String[]
* @throws Exception */
public static void main(String... args) throws Exception {
// Demonstrates the creation and parsing of a simple Activity Object
// (we'll use this to store the output...)
ByteArrayOutputStream out =
new ByteArrayOutputStream();
// The IO object handles all of the reading and writing of the object
IO io = IO.make().prettyPrint().get();
// Create the Activity... The API uses a Fluent Generator pattern
Activity activity =
activity()
.verb("post")
.actor(
object()
.objectType(
object()
.id("http://schema.example.net/Person")
.displayName("Person")
.alias("person"))
.id("acct:joe@example.com")
.displayName("Joe Smith")
)
.object(
object("note")
.id("http://example.net/posts/1")
.title(
nlv()
.set("en", "This is the title")
.set("fr", "C'est le titre"))
)
.audience(TO,
"urn:social:everyone",
"acct:mary@example.net")
.audience(CC,
"urn:social:extended")
.action("embed", "http://xml.example.org/foo")
.pending()
.get();
// The Activity object is immutable...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
System.out.println(activity.status());
// let's write it out to our outputstream
activity.writeTo(out, io);
// now let's parse it back in
ByteArrayInputStream in =
new ByteArrayInputStream(
out.toByteArray());
activity = io.readAsActivity(in);
// We get back the same thing...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
System.out.println(activity.status());
// If you want to see what was serialized,
// simply write out to stdout...
activity.writeTo(System.out, io);
}
}

View File

@ -0,0 +1,60 @@
package com.ibm.common.activitystreams.examples;
import static com.ibm.common.activitystreams.Makers.activity;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.ibm.common.activitystreams.Activity;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class Simple5 {
private Simple5() {}
/**
* Method main.
* @param args String[]
* @throws Exception */
public static void main(String... args) throws Exception {
// Create the Activity... The API uses a Fluent Generator pattern
Activity activity =
activity()
.verb("post")
.actor("acct:joe@example.org")
.object("http://example.net/posts/1")
.action("like", "http://example.org/actions/like")
.updatedNow()
.get();
// The Activity object is immutable...
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
// Activity objects are serializable
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(activity);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
activity = (Activity) ois.readObject();
System.out.println(activity.verb());
System.out.println(activity.actor());
System.out.println(activity.object());
System.out.println(activity.actions().get("like"));
System.out.println(activity.updated());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,213 @@
package com.ibm.common.activitystreams;
import java.io.Serializable;
import java.util.Map;
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.ibm.common.activitystreams.util.AbstractDictionaryObject;
/**
* <p>The value of the "actions" property... used to map potential verbs
* with objects capable of "handling" those verbs. Each of the keys
* must be a valid verb (either a token or an absolute IRI). </p>
*
* <p>Specifying Actions while creating AS Objects:</p>
*
* <pre>
* import static com.ibm.common.activitystreams.Makers.object;
* import static com.ibm.common.activitystreams.Makers.actions;
* import static com.ibm.common.activitystreams.actions.ActionMakers.intentAction;
* ...
*
* ASObject obj = object()
* .action("like", "http://example.org/like-action")
* .action("follow", intentAction())
* .get();
* </pre>
*
* <p>Accessing Actions when consuming AS Objects:</p>
*
* <pre>
* ActionsValue actions = obj.actions();
* for (LinkValue lv : actions.get("like")) {
* ...
* }
* </pre>
*
* <p>The Actions object itself is a JSON Dictonary that maps
* verb identifiers to a Link Value that contains one or more
* Action Handlers. A call to the get(...) method returns an
* Iterable of Simple or Object LinkValue instances representing
* each of the associated Action Handlers.</p>
*
* <p>A Serialized Activity Stream object with Actions:
* <pre>
* {
* "objectType": "note",
* "displayName": "My Note",
* "actions": {
* "like": "http://example.org/like-action",
* "follow": {
* "objectType": "IntentActionHandler",
* "displayName": "Follow updates to this note!"
* }
* }
* }
* </pre>
*
* @author james
* @version $Revision: 1.0 $
*/
public final class ActionsValue
extends AbstractDictionaryObject<LinkValue>
implements Serializable {
/**
* Builder for ActionsValue objects.
* <pre>
* Makers.actions()
* .set("like", "http://example.org/like-action")
* .set("follow", ActionMakers.intentAction())
* .get();
* </pre>
*/
public static final class Builder
extends AbstractDictionaryObject.AbstractBuilder
<LinkValue, ActionsValue, Builder> {
protected Builder() {}
/**
* Add an action handler for the given verb.
* Calling this multiple times results in
* multiple action handlers.
* @param verb String
* @param iri String
* @return Builder
*/
public Builder set(String verb, String iri) {
return set(
verb,
LinkValue.SimpleLinkValue.make(iri));
}
@Override
public Builder set(String key, LinkValue x) {
return super.link(key, x);
}
@Override
public Builder set(String key, Supplier<? extends LinkValue> x) {
return super.link(key, x);
}
/**
* Get the built ActionsValue instance
* @return ParametersValue
* @see com.google.common.base.Supplier#get()
**/
public ActionsValue get() {
return new ActionsValue(this);
}
}
private ActionsValue(Builder builder) {
super(builder);
}
/**
* Get all Action Handlers associated with the given verb.
* @param verb String
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> get(String verb) {
return super.getIterable(verb);
}
/**
* Get all Action Handlers associated with the given verb
* that satisfy the given filter
* @param verb String
* @param filter Predicate<LinkValue>
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> get(
String verb,
Predicate<LinkValue> filter) {
return super.getIterable(verb, filter);
}
/**
* Get all Action Handlers associated with the given verb,
* transformed using the given Transform function
* @param verb String
* @param transform Function<LinkValue,Y>
* @return java.util.Iterable<Y>
*/
public <Y> Iterable<Y> get(
String verb,
Function<LinkValue, Y> transform) {
return super.getIterable(verb, transform);
}
/**
* Get all Action Handlers associated with the given verb,
* filtered using the given Predicate and transformed
* using the given Transform function.
* @param verb String
* @param filter Predicate<LinkValue>
* @param transform Function<LinkValue,Y>
* @return java.util.Iterable<Y>
*/
public <Y> Iterable<Y> get(
String verb,
Predicate<LinkValue> filter,
Function<LinkValue, Y> transform) {
return super.getIterable(verb, filter, transform);
}
/**
* True if there is at least one Action Handler associated
* with the given verb
* @param verb String
* @return boolean
*/
public boolean hasAtLeastOne(String verb) {
return super.hasAtLeastOne(verb);
}
// Java serialization support
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private ImmutableMap<String,Object> map;
SerializedForm(ActionsValue obj) {
ImmutableMap.Builder<String,Object> builder =
ImmutableMap.builder();
for (String key : obj)
builder.put(key, obj.get(key));
this.map = builder.build();
}
@SuppressWarnings("unchecked")
Object readResolve()
throws java.io.ObjectStreamException {
ActionsValue.Builder builder =
Makers.actions();
for (Map.Entry<String,Object> entry : map.entrySet()) {
Iterable<LinkValue> list = (Iterable<LinkValue>) entry.getValue();
for (LinkValue link : list)
builder.set(entry.getKey(), link);
}
return builder.get();
}
}
}

View File

@ -0,0 +1,832 @@
package com.ibm.common.activitystreams;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.Math.floor;
import static java.lang.Math.ceil;
import static com.ibm.common.activitystreams.Makers.linkValue;
import static com.ibm.common.activitystreams.Makers.type;
import java.io.ObjectStreamException;
import java.io.Serializable;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
/**
* An Activity Streams 2.0 Activity
*
* <p>Creating an Activity:</p>
* <pre>
* import static com.ibm.common.activitystreams.Makers.activity;
* import static com.ibm.common.activitystreams.Makers.object;
* ...
*
* Activity activity = activity()
* .actor("acct:joe@example.org")
* .verb("post")
* .object(object().content("This is a note"))
* .get();
* </pre>
*
* <p>Consuming an Activity:</p>
* <pre>
* Activity activity = IO.makeDefault().readAsActivity(...);
*
* System.out.println(activity.verbAsString());
* ASObject actor = activity.firstActor();
* ASObject object = activity.firstObject();
* </pre>
*
* @author james
* @version $Revision: 1.0 $
*/
public class Activity
extends ASObject
implements Serializable {
public static enum Audience {
/**
* Primary public audience
**/
TO,
/**
* Primary private audience
**/
BTO,
/**
* Secondary public audience
**/
CC,
/**
* Secondary private audience
**/
BCC,
/**
* Public origin
**/
FROM,
/**
* Private origin
**/
BFROM;
private final String label;
private Audience() {
this.label = name().toLowerCase();
}
/**
* Returns the "from" target(s)
* @return java.util.Iterable&lt;LinkValue>*/
private Iterable<LinkValue> get(
Activity activity) {
return activity.links(label);
}
private Iterable<LinkValue> get(
Activity activity,
Predicate<? super LinkValue> filter) {
return activity.links(label, filter);
}
private LinkValue first(Activity activity) {
return activity.firstLink(label);
}
private LinkValue firstMatching(
Activity activity,
Predicate<? super LinkValue> test) {
return activity.firstMatchingLink(label, test);
}
}
public static enum Status {
/** The Activity is tentatively scheduled to begin **/
TENTATIVE,
/** The Activity is scheduled to begin **/
PENDING,
/** The Activity has been completed **/
COMPLETED,
/** The Activity has been canceled or aborted **/
CANCELED,
/** The Activity is currently active **/
ACTIVE,
/** The Activity has been voided. **/
VOIDED,
OTHER
}
/**
*
* Builder for concrete Activity object instances.
*
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
extends Activity.AbstractBuilder<Activity,Activity.Builder> {
/**
* Get the built Activity object
* @return Activity
* @see com.google.common.base.Supplier#get()
*/
public Activity get() {
return new Activity(this);
}
}
/**
* Ensures that the priority value is within the acceptable range (0.0-1.0)
* @param d double
* @return double
*/
private static double checkPriority(double d) {
checkArgument(floor(d) >= 0 && ceil(d) >= 1);
return d;
}
/**
* Abstract builder for Activity classes. This is defined this way
* to make it easier to build extensions of the Activity class.
* @author james
* @version $Revision: 1.0 $
*/
@SuppressWarnings("unchecked")
public static abstract class AbstractBuilder
<A extends Activity, B extends AbstractBuilder<A,B>>
extends ASObject.AbstractBuilder<A, B> {
/**
* Set the Activity status property.
* @param status Status
* @return B
*/
public B status(Status status) {
if (status != null)
set("status", status);
return (B)this;
}
/**
* Mark the status of this activity as being "voided"
* @return B
*/
public B voided() {
return status(Status.VOIDED);
}
/**
* Mark the status of this activity as being "tentative"
* @return B
*/
public B tentative() {
return status(Status.TENTATIVE);
}
/**
* Mark the status of this activity as being "pending"
* @return B
*/
public B pending() {
return status(Status.PENDING);
}
/**
* Mark the status of this activity as being "active"
* @return B
*/
public B active() {
return status(Status.ACTIVE);
}
/**
* Mark the status of this activity as being "canceled"
* @return B
*/
public B canceled() {
return status(Status.CANCELED);
}
/**
* Mark the status of this activity as being "completed"
* @return B
*/
public B completed() {
return status(Status.COMPLETED);
}
/**
* Set the verb for this activity
* @param iri String
* @return B
*/
public B verb(String iri) {
set("verb", type(iri));
return (B)this;
}
/**
* Set the verb for this activity
* @param tv TypeValue
* @return B
*/
public B verb(TypeValue tv) {
set("verb", tv);
return (B)this;
}
/**
* Set the verb for this activity
* @param tv Supplier<? extends TypeValue>
* @return B
*/
public B verb(Supplier<? extends TypeValue> tv) {
return verb(tv.get());
}
/**
* Set a participant that indirectly contributed to the activity.
* @param url String
* @return B
**/
public B participant(String url, String... urls) {
if (url != null)
link("participant", linkValue(url));
if (urls != null)
for (String u : urls)
link("participant", linkValue(u));
return (B)this;
}
/**
* Set a participant that indirectly contributed to the activity
* @param link LinkValue
* @return B
*/
public B participant(LinkValue link, LinkValue... links) {
if (link != null)
link("participant", link);
if (links != null)
for (LinkValue l : links)
link("participant", l);
return (B)this;
}
/**
* Set a participant that indirectly contributed to the activity
* @param link Supplier<? extends LinkValue>
* @return B
*/
public B participant(Supplier<? extends LinkValue> link) {
return link("participant", link.get());
}
/**
* Set the instrument used to complete the activity
* @param url String
* @return B
*/
public B instrument(String url, String... urls) {
if (url != null)
link("instrument", linkValue(url));
if (urls != null)
for (String u : urls)
link("instument", linkValue(u));
return (B)this;
}
/**
* Set the instrument used to complete the activity
* @param link LinkValue
* @return B
*/
public B instrument(LinkValue link, LinkValue... links) {
if (link != null)
link("instrument", link);
if (links != null)
for (LinkValue l : links)
link("instrument", l);
return (B)this;
}
/**
* Set the instrument used to complete the activity
* @param link Supplier<? extends LinkValue>
* @return B
*/
public B instrument(Supplier<? extends LinkValue> link) {
return link("instrument", link.get());
}
/**
* Set the primary actor/agent for this activity
* @param url String
* @return B
*/
public B actor(String url, String... urls) {
if (url != null)
link("actor", linkValue(url));
if (urls != null)
for (String u : urls)
link("actor", linkValue(u));
return (B)this;
}
/**
* Set the primary actor/agent for this activity
* @param link LinkValue
* @return B
*/
public B actor(LinkValue link, LinkValue... links) {
if (link != null)
link("actor", link);
if (links != null)
for (LinkValue l : links)
link("actor", l);
return (B)this;
}
/**
* Set the actor
* @param link Supplier<? extends LinkValue>
* @return B
*/
public B actor(Supplier<? extends LinkValue> link) {
return link("actor", link.get());
}
/**
* Set the direct object of this activity (the object that has been
* or will be acted upon)
* @param url String
* @return B
*/
public B object(String url, String... urls) {
if (url != null)
link("object", linkValue(url));
if (urls != null)
for (String u : urls)
link("object", linkValue(u));
return (B)this;
}
/**
* Set the direct object of this activity (the object that has been
* or will be acted upon)
* @param link LinkValue
* @return B
*/
public B object(LinkValue link, LinkValue... links) {
if (link != null)
link("object", link);
if (links != null)
for (LinkValue l : links)
link("object", l);
return (B)this;
}
/**
* Set the direct object of this activity (the object that has been
* or will be acted upon)
* @param link Supplier<? extends LinkValue>
* @return B
*/
public B object(Supplier<? extends LinkValue> link) {
return link("object", link.get());
}
/**
* Set an object that is indirectly affected by the activity
* @param url String
* @return B
*/
public B target(String url, String... urls) {
if (url != null)
link("target", linkValue(url));
if (urls != null)
for (String u : urls)
link("target", linkValue(u));
return (B)this;
}
/**
* Set an object that is indirectly affected by the activity
* @param link LinkValue
* @return B
*/
public B target(LinkValue link, LinkValue... links) {
if (link != null)
link("target", link);
if (links != null)
for (LinkValue l : links)
link("target", l);
return (B)this;
}
/**
* Set an object that is indirectly affected by the activity
* @param link Supplier<? extends LinkValue>
* @return B
*/
public B target(Supplier<? extends LinkValue> link) {
return link("target", link.get());
}
/**
* Set a URI that describes the result of this activity
* @param url String
* @return B
*/
public B result(String url, String... urls) {
if (url != null)
link("result", linkValue(url));
if (urls != null)
for (String u : urls)
link("result", linkValue(u));
return (B)this;
}
/**
* Set an object that describes the result of this activity
* @param link LinkValue
* @return B
*/
public B result(LinkValue link, LinkValue... links) {
if (link != null)
link("result", link);
if (links != null)
for (LinkValue l : links)
link("result", l);
return (B)this;
}
/**
* Set an object that describes the result of this activity
* @param link Supplier<? extends LinkValue>
* @return B
*/
public B result(Supplier<? extends LinkValue> link) {
return link("result", link.get());
}
/**
* Set the audience for this activity
* @param audience
* @param url
* @param urls
* @return B
*/
public B audience(Audience audience, String url, String... urls) {
link(audience.label, linkValue(url));
for (String u : urls)
link(audience.label, u);
return (B)this;
}
/**
* Set the audience for this activity
* @param audience
* @param link
* @param links
* @return B
*/
public B audience(Audience audience, LinkValue link, LinkValue... links) {
link(audience.label, link);
for (LinkValue lv : links)
link(audience.label, lv);
return (B)this;
}
/**
* Set the audience for this activity
* @param audience
* @param link
* @return B
*/
public B audience(Audience audience, Supplier<? extends LinkValue> link) {
return link(audience.label, link);
}
/**
* Set the priority as value in the range 0.00 to 1.00.
* Value will be checked to ensure it is within the valid range.
* The value SHOULD be limited to two decimal places but the
* number of decimals will not be checked.
* @param d double
* @return B
* @throws IllegalArgumentException if the value is not within 0.00-1.00
*/
public B priority(double d) {
return set("priority", checkPriority(d));
}
}
Activity(Activity.AbstractBuilder<?, ?> builder) {
super(builder);
}
/**
* returns the verb as TypeValue object
* @return T
**/
public <T extends TypeValue>T verb() {
return this.<T>get("verb");
}
/**
* Returns the verb as a string
* @return String
**/
public String verbString() {
return typeValueAsString("verb");
}
/**
* Return the participant(s)
* @return java.util.Iterable&lt;LinkValue>
**/
public Iterable<LinkValue> participant() {
return links("participant");
}
/**
* Return the matching participant(s)
* @param filter
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> participant(Predicate<? super LinkValue> filter) {
return links("participant", filter);
}
/**
* Return the first paticipant
* @return LinkValue
*/
public LinkValue firstParticipant() {
return firstLink("participant");
}
/**
* Return the first matching participant
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingParticipant(Predicate<? super LinkValue> test) {
return firstMatchingLink("participan", test);
}
/**
* Return the instrument(s)
* @return java.util.Iterable&lt;LinkValue>
**/
public Iterable<LinkValue> instrument() {
return links("instrument");
}
/**
* Return the matching instrument(s)
* @param filter
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> instrument(Predicate<? super LinkValue> filter) {
return links("instrument", filter);
}
/**
* Return the first instrument
* @return LinkValue
*/
public LinkValue firstInstrument() {
return firstLink("instrument");
}
/**
* Return the first matching instrument
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingInstrument(Predicate<? super LinkValue> test) {
return firstMatchingLink("instrument", test);
}
/**
* Returns the actor(s)
* @return java.util.Iterable&lt;LinkValue>
**/
public Iterable<LinkValue> actor() {
return links("actor");
}
/**
* Return the matching actor(s)
* @param filter
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> actor(Predicate<? super LinkValue> filter) {
return links("actor", filter);
}
/**
* Return the first actor
* @return LinkValue
*/
public LinkValue firstActor() {
return firstLink("actor");
}
/**
* Return the first matching actor
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingActor(Predicate<? super LinkValue> test) {
return firstMatchingLink("actor", test);
}
/**
* Returns the object(s)
* @return java.util.Iterable&lt;LinkValue>
**/
public Iterable<LinkValue> object() {
return links("object");
}
/**
* Return the matching object(s)
* @param filter
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> object(Predicate<? super LinkValue> filter) {
return links("object", filter);
}
/**
* Return the first object
* @return LinkValue
*/
public LinkValue firstObject() {
return firstLink("object");
}
/**
* Return the first matching object
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingObject(Predicate<? super LinkValue> test) {
return firstMatchingLink("object", test);
}
/**
* Returns the target(s)
* @return java.util.Iterable&lt;LinkValue>
**/
public Iterable<LinkValue> target() {
return links("target");
}
/**
* Return the matching target(s)
* @param filter
* @return java.util.Iterable<LinkValue>
*/
public Iterable<LinkValue> target(Predicate<? super LinkValue> filter) {
return links("target", filter);
}
/**
* Return the first target
* @return LinkValue
*/
public LinkValue firstTarget() {
return firstLink("target");
}
/**
* Return the first matching target
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingTarget(Predicate<? super LinkValue> test) {
return firstMatchingLink("target", test);
}
/**
* Returns the result(s)
* @return java.util.Iterable&lt;LinkValue>
**/
public Iterable<LinkValue> result() {
return links("result");
}
/**
* Returns the matching result(s)
* @param filter
* @return java.util.Iterable&lt;LinkValue>
*/
public Iterable<LinkValue> result(Predicate<? super LinkValue> filter) {
return links("result", filter);
}
/**
* Return the first result
* @return LinkValue
*/
public LinkValue firstResult() {
return firstLink("result");
}
/**
* Return the first matching result
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingResult(Predicate<? super LinkValue> test) {
return firstMatchingLink("result", test);
}
/**
* Returns the priority.
* @return double
* @throws IllegalArgumentException if the priority is not within
* the range 0.00-1.00
**/
public double priority() {
return checkPriority(getDouble("priority"));
}
/**
* Return the audience for this activity
* @param audience
* @return java.util.Iterable&lt;LinkValue>
*/
public Iterable<LinkValue> audience(
Audience audience) {
return audience.get(this);
}
/**
* Return the audience for this activity
* @param audience
* @param filter
* @return java.util.Iterable&lt;LinkValue>
*/
public Iterable<LinkValue> audience(
Audience audience,
Predicate<? super LinkValue> filter) {
return audience.get(this,filter);
}
/**
* Return the first audience for this activity
* @param audience
* @return LinkValue
*/
public LinkValue firstAudience(Audience audience) {
return audience.first(this);
}
/**
* Return the first matching audience for this activity
* @param audience
* @param test
* @return LinkValue
*/
public LinkValue firstMatchingAudience(
Audience audience,
Predicate<? super LinkValue> test) {
return audience.firstMatching(this, test);
}
/**
* Return the status of this activity
* @return Status
*/
public Status status() {
return get("status");
}
// Java Serialization Support
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Activity> {
protected SerializedForm(Activity obj) {
super(obj);
}
private static final long serialVersionUID = -1975376657749952999L;
protected Activity.Builder builder() {
return Makers.activity();
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
}
}

View File

@ -0,0 +1,504 @@
package com.ibm.common.activitystreams;
import static com.google.common.base.Preconditions.checkArgument;
import static com.ibm.common.activitystreams.Makers.linkValue;
import static com.google.common.collect.Iterables.filter;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import org.joda.time.DateTime;
import org.joda.time.ReadableDuration;
import org.joda.time.ReadablePeriod;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
*
* An Activity Streams collection object
*
* <pre>
* import static com.ibm.common.activitystreams.Makers.collection;
* import static com.ibm.common.activitystreams.Makers.object;
* ...
*
* Collection collection = collection()
* .items(object()...)
* .items(object()...)
* .get();
* </pre>
*
* @author james
* @version $Revision: 1.0 $
*/
@SuppressWarnings("unchecked")
public class Collection
extends ASObject
implements Serializable {
/** Standardized Paging Links **/
public static enum Page {
/**
* Reference to the first page in the logical set
**/
FIRST,
/**
* Reference to the next page in the logical set
**/
NEXT,
/**
* Reference to the final page in the logical set
* **/
LAST,
/**
* Reference to the previous page in the logical set
**/
PREVIOUS,
/**
* Reference to the previous page in the logical set (treated as an alias for "previous")
* @deprecated Use Page.PREVIOUS instead
**/
PREV,
/**
* Reference to the page containing the most recently published/updated
* items in the logical set
**/
CURRENT,
/**
* Reference to this page
**/
SELF;
private final String label;
private Page() {
this.label = name().toLowerCase();
}
private String checkPrev(Collection col, String or) {
if (this == PREVIOUS) {
if (!col.has(label) && col.has(PREV.label))
return PREV.label;
} else if (this == PREV) {
if (!col.has(label) && col.has(PREVIOUS.label))
return PREVIOUS.label;
}
return or;
}
private Iterable<LinkValue> links(Collection col) {
return col.links(checkPrev(col,label));
}
private Iterable<LinkValue> links(
Collection col,
Predicate<? super LinkValue> filter) {
return col.links(checkPrev(col,label), filter);
}
private LinkValue first(Collection col) {
return col.firstLink(checkPrev(col,label));
}
private LinkValue firstMatching(
Collection col,
Predicate<? super LinkValue> filter) {
return col.firstMatchingLink(checkPrev(col,label), filter);
}
}
/**
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
extends Collection.AbstractBuilder<Collection,Collection.Builder> {
/**
* Method create.
* @return Collection */
protected Collection create() {
return new Collection(this);
}
}
/**
* @author james
* @version $Revision: 1.0 $
*/
public static abstract class AbstractBuilder
<A extends Collection, B extends Collection.AbstractBuilder<A,B>>
extends ASObject.AbstractBuilder<A, B> {
protected final ImmutableList.Builder<ASObject> list =
ImmutableList.builder();
/**
* Method create.
* @return A
**/
protected abstract A create();
/**
* Method get.
* @return A
* @see com.google.common.base.Supplier#get()
**/
public A get() {
set("items", list.build());
return create();
}
/**
* Add items to this collection
* @param objs java.util.Iterable<? extends ASObject>
* @return B
*/
public B items(Iterable<? extends ASObject> objs) {
if (objs == null)
return (B)this;
for (ASObject obj : objs)
items(obj);
return (B)this;
}
/**
* Add items to this collection
* @param obj ASObject The object to add
* @param objs ASObject[] Additional objects to add (vararg)
* @return B
**/
public B items(ASObject obj, ASObject... objs) {
if (obj == null)
return (B)this;
list.add(obj);
if (objs != null)
for (ASObject o : objs)
list.add(o);
return (B)this;
}
/**
* Add an item to this collection
* @param obj com.google.common.base.Supplier<? extends ASObject>
* @return B
**/
public B items(Supplier<? extends ASObject> obj) {
if (obj == null)
return (B)this;
items(obj.get());
return (B)this;
}
/**
* Set the total number of items (must be non-negative)
* @param i int
* @return B
**/
public B totalItems(int i) {
checkArgument(i >= 0);
set("totalItems", i);
return (B)this;
}
/**
* Set the number of items per page (must be non-negative)
* @param i int
* @return B
**/
public B itemsPerPage(int i) {
checkArgument(i >= 0);
set("itemsPerPage", i);
return (B)this;
}
/**
* Set the starting index (must be non-negative)
* @param i int
* @return B
**/
public B startIndex(int i) {
checkArgument(i >= 0);
set("startIndex", i);
return (B)this;
}
/**
* Specify that the collection contains items updated after the specified time
* @param dt DateTime
* @return B
**/
public B itemsAfter(DateTime dt) {
return _dt("itemsAfter", dt);
}
/**
* Specify that the collection contains items updated after right now
* @return B
*/
public B itemsAfterNow() {
return _dtNow("itemsAfter");
}
/**
* Specify that the collection contains items updated a specific duration after now
* @param duration Duration
* @return B
*/
public B itemsAfterFromNow(ReadableDuration duration) {
return _dtFromNow("itemsAfter", duration);
}
/**
* Specify that the collection contains items updated a specific period after now
* @param period
* @return B
*/
public B itemsAfterFromNow(ReadablePeriod period) {
return _dtFromNow("itemsAfter", period);
}
/**
* Specify that the collection contains items updated a specific duration after now
* @param v long
* @param unit TimeUnit
* @return B
**/
public B itemsAfterFromNow(long v, TimeUnit unit) {
return _dtFromNow("itemsAfter", v, unit);
}
/**
* Specify that the collection contains items updated before a specific time
* @param dt DateTime
* @return B
**/
public B itemsBefore(DateTime dt) {
return _dt("itemsBefore", dt);
}
/**
* Specify that the collection contains items updated before now
* @return B
*/
public B itemsBeforeNow() {
return _dtNow("itemsBefore");
}
/**
* Specify that the collection contains items updated a specific duration
* before now
* @param duration Duration
* @return B
*/
public B itemsBeforeFromNow(ReadableDuration duration) {
return _dtFromNow("itemsBefore", duration);
}
/**
* Specify that the collection contains items updated a specific period
* before now
* @param period
* @return B
*/
public B itemsBeforeFromNow(ReadablePeriod period) {
return _dtFromNow("itemsBefore", period);
}
/**
* Method itemsBeforeFromNow.
* @param v long
* @param unit TimeUnit
* @return B
**/
public B itemsBeforeFromNow(long v, TimeUnit unit) {
return _dtFromNow("itemsBefore", v, unit);
}
/**
* Adds a paging link
* <pre>
* Collection collection = Makers.collection()
* .pageLink(Page.NEXT, "http://example.org")
* .get();
* </pre>
* @param page
* @param url
* @return B
*/
public B pageLink(Page page, String url) {
return link(page.label, linkValue(url));
}
/**
* Adds a paging link
* @param page
* @param link
* @return B
*/
public B pageLink(Page page, LinkValue link) {
return link(page.label, link);
}
/**
* Adds a paging link
* @param page
* @param link
* @return B
*/
public B pageLink(Page page, Supplier<? extends LinkValue> link) {
return link(page.label, link);
}
}
/**
* Constructor for Collection.
* @param builder Collection.AbstractBuilder<?,?>
*/
Collection(Collection.AbstractBuilder<?, ?> builder) {
super(builder);
}
/**
* Returns the total number of items
* @return int
**/
public int totalItems() {
return getInt("totalItems");
}
/**
* If not null, indicates that the collection only contains items
* updated after the given instant
* @return DateTime
**/
public DateTime itemsAfter() {
return this.getDateTime("itemsAfter");
}
/**
* If not null, indicates that the collection only contains items
* updated before the given instant
* @return DateTime
* */
public DateTime itemsBefore() {
return this.getDateTime("itemsBefore");
}
/**
* Returns the number of items per page
* @return int
**/
public int itemsPerPage() {
return this.getInt("itemsPerPage");
}
/**
* Returns the start index for this page
* @return int
**/
public int startIndex() {
return this.getInt("startIndex");
}
/**
* Returns a listing of Paging links that
* exist on this collection
* @return Iterable&lt;Page>
*/
public Iterable<Page> pages() {
ImmutableSet.Builder<Page> pages =
ImmutableSet.builder();
for (Page page : Page.values())
if (has(page.label))
pages.add(page);
return pages.build();
}
/**
* Returns a listing of Paging LinkValues
* @param page Page The type of paging link to return
* @return Iterable&lt;LinkValue>
*/
public Iterable<LinkValue> pageLink(
Page page) {
return page.links(this);
}
/**
* Returns a listing of Paging LinkValues
* @param page Page The type of paging link to return
* @param filter Predicate<? super LinkValue> A filter
* @return Iterable&lt;LinkValue>
*/
public Iterable<LinkValue> pageLink(
Page page,
Predicate<? super LinkValue> filter) {
return page.links(this,filter);
}
/**
* Returns the first matching paging LinkValue
* @param page Page The type of paging link to return
* @return LinkValue
*/
public LinkValue firstPageLink(
Page page) {
return page.first(this);
}
/**
* Returns the first matching paging LinkValue
* @param page Page the type of paging link to return
* @param test com.google.common.base.Predicate<? super LinkValue> a filter
* @return LinkValue
*/
public LinkValue firstMatchingPageLink(
Page page,
Predicate<? super LinkValue> test) {
return page.firstMatching(this,test);
}
/**
* Returns the collection of items
* @return java.util.Iterable<A>
**/
public <A extends ASObject>Iterable<A> items() {
return this.<Iterable<A>>get("items");
}
/**
* Returns a filtered collection of items
* @param filter com.google.common.base.Predicate<? super A> filter
* @return java.util.Iterable<A>
*/
public <A extends ASObject>Iterable<A> items(
Predicate<? super A> filter) {
return filter(this.<A>items(), filter);
}
// Java Serialization Support
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Collection> {
protected SerializedForm(Collection obj) {
super(obj);
}
private static final long serialVersionUID = -1975376657749952999L;
protected Collection.Builder builder() {
return Makers.collection();
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
}
}

View File

@ -0,0 +1,614 @@
package com.ibm.common.activitystreams;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.ibm.common.activitystreams.internal.Adapter;
import com.ibm.common.activitystreams.internal.GsonWrapper;
import com.ibm.common.activitystreams.internal.Schema;
import com.ibm.common.activitystreams.util.Module;
/**
* The IO object is responsible for serializing and deserializing
* Activity Stream objects. Instances of IO should be created and
* defined statically. IO instances are threadsafe and immutable
* once created.
*
* <p>You can choose to use one of the default IO instances:</p>
*
* <pre>
* public static final IO io = IO.makeDefault();
*
* public static final IO prettyIo = IO.makeDefaultPrettyPrint();
* </pre>
*
* <p>Or you can use the IO.Builder to construct and configure your
* own IO instance with custom adapters, object properties and
* type mappings:</p>
*
* <pre>
* import static
*
* public static final IO io =
* IO.make()
* .schema(
* Makers.makeSchema().map(
* Schema.object.template()
* .as("foo", Foo.class)))
* .adapter(Foo.class, new MyFooAdapter())
* .get();
* </pre>
*
* <p>Once created, you can use IO instances to parse Activity Streams
* documents:</p>
*
* <pre>
* InputStream in = ...
* Activity activity = io.readAsActivity(in);
* </pre>
*
* <p>Or can use the IO instance to serialize:</p>
*
* <pre>
* OutputStream out = ...
* Activity activity = ...
* activity.writeTo(out, io);
* </pre>
*
* @author james
* @version $Revision: 1.0 $
*/
public final class IO {
/**
* Create a new IO.Builder
* @return Builder */
public static Builder make() {
return new Builder();
}
/**
* Create a new IO.Builder that uses the given schema
* @param schema Schema
* @return IO
*/
public static IO makeWithSchema(Schema schema) {
return make().schema(schema).get();
}
/**
* Create a new IO.Builder that uses the given schema
* @param schema Supplier<? extends Schema>
* @return IO
*/
public static IO makeWithSchema(Supplier<? extends Schema> schema) {
return makeWithSchema(schema.get());
}
/**
* Make or return the default IO instance
* @return IO
**/
public static IO makeDefault(Module... modules) {
IO.Builder builder = make();
if (modules != null)
for (Module mod : modules)
builder.using(mod);
return builder.get();
}
/**
* Make or return a default IO instance with Pretty Print enabled
* @return IO
*/
public static IO makeDefaultPrettyPrint(Module... modules) {
IO.Builder builder = make().prettyPrint();
if (modules != null)
for (Module mod : modules)
builder.using(mod);
return builder.get();
}
public static class Builder
implements Supplier<IO> {
private final GsonWrapper.Builder inner =
GsonWrapper.make();
private Schema schema;
private final ImmutableSet.Builder<Module> modules =
ImmutableSet.builder();
public Builder using(Module module) {
modules.add(module);
return this;
}
public Builder typeValueResolver(Function<TypeValue,TypeValue> resolver) {
inner.typeValueResolver(resolver);
return this;
}
/**
* Turn pretty print on or off
* @param on boolean
* @return Builder
**/
public Builder prettyPrint(boolean on) {
inner.prettyPrint(on);
return this;
}
/**
* Turn pretty print on
* @return Builder
**/
public Builder prettyPrint() {
return prettyPrint(true);
}
/**
* Add an adapter
* @param type Class<? extends T>
* @param adapter Adapter<T>
* @return Builder
**/
public <T>Builder adapter(
Class<? extends T> type,
Adapter<T> adapter) {
inner.adapter(type, adapter);
return this;
}
/**
* Add an adapter
* @param type Class&lt;? extends T>
* @return Builder
*/
public <T>Builder adapter(
Class<? extends T> type) {
return adapter(type,null);
}
/**
* Add an adapter
* @param type Class&lt;? extends T>
* @return Builder
*/
public <T>Builder hierarchicalAdapter(
Class<? extends T> type) {
return hierarchicalAdapter(type,null);
}
/**
* Add an adapter.
* @param type Class<? extends T>
* @param adapter Adapter<T>
* @param hier boolean
* @return Builder
**/
public <T>Builder hierarchicalAdapter(
Class<? extends T> type,
Adapter<T> adapter) {
inner.adapter(type, adapter, true);
return this;
}
/**
* Set the schema
* @param schema Schema
* @return Builder
**/
public Builder schema(Schema schema) {
//inner.schema(schema);
this.schema = schema;
return this;
}
/**
* Set the schema.
* @param schema Supplier<Schema>
* @return Builder
**/
public Builder schema(Supplier<Schema> schema) {
return schema(schema.get());
}
public IO get() {
Iterable<Module> mods = modules.build();
Schema schema = this.schema;
if (schema == null) {
Schema.Builder builder = Schema.make();
for (Module mod : mods)
mod.apply(builder);
schema = builder.get();
}
inner.schema(schema);
for (Module module : modules.build())
module.apply(this, schema);
return new IO(this);
}
}
private final GsonWrapper gson;
protected IO(Builder builder) {
this.gson =
builder.inner.get();
}
/**
* Write the given object
* @param w Writable
* @return String
*/
public String write(Writable w) {
StringWriter sw = new StringWriter();
w.writeTo(sw,this);
return sw.toString();
}
/**
* Asynchronously write the given object
* @param w
* @param executor
* @return java.util.concurrent.Future&lt;String>
*/
public Future<String> write(
final Writable w,
ExecutorService executor) {
return executor.submit(
new Callable<String>() {
public String call() throws Exception {
return write(w);
}
}
);
}
/**
* Write the object to the given outputstream
* @param w Writable
* @param out OutputStream
*/
public void write(Writable w, OutputStream out) {
gson.write(w,out);
}
/**
* Asychronously write the object to the given output stream
* @param w
* @param out
* @param executor
* @return java.util.concurrent.Future&lt;?>
*/
public Future<?> write(
final Writable w,
final OutputStream out,
ExecutorService executor) {
return executor.submit(
new Runnable() {
public void run() {
write(w, out);
}
}
);
}
/**
* Asychronously write the object to the given writer
* @param w
* @param out
* @param executor
* @return java.util.concurrent.Future&lt;?>
*/
public Future<?> write(
final Writable w,
final Writer out,
ExecutorService executor) {
return executor.submit(
new Runnable() {
public void run() {
write(w, out);
}
}
);
}
/**
* Write the object to the given writer
* @param w Writable
* @param out Writer
*/
public void write(Writable w, Writer out) {
gson.write(w,out);
}
/**
* Asynchronously read the given input stream and
* return a parsed object of the given type
* @param in
* @param type
* @param executor
* @return java.util.concurrent.Future&lt;A extends ASObject>
*/
public <A extends ASObject>Future<A> readAs(
final InputStream in,
final Class<? extends A> type,
ExecutorService executor) {
return executor.submit(
new Callable<A>() {
public A call() throws Exception {
return readAs(in, type);
}
}
);
}
/**
* Read the given input stream and return a parsed object
* of the given type
* @param in InputStream
* @param type Class<? extends A>
* @return A */
public <A extends ASObject>A readAs(
InputStream in,
Class<? extends A> type) {
return gson.<A>readAs(in, type);
}
/**
* Asynchronously read the given reader and return a parsed
* object of the given type
* @param in
* @param type
* @param executor
* @return java.util.concurrent.Future&lt;A extends ASObject>
*/
public <A extends ASObject>Future<A> readAs(
final Reader in,
final Class<? extends A> type,
ExecutorService executor) {
return executor.submit(
new Callable<A>() {
public A call() throws Exception {
return readAs(in, type);
}
}
);
}
/**
* Read the given reader and return a parsed object of the given type
* @param in Reader
* @param type Class<? extends A>
* @return A */
public <A extends ASObject>A readAs(
Reader in,
Class<? extends A> type) {
return gson.<A>readAs(in, type);
}
/**
* Asynchronously read the given string and return a parsed object of
* the given type
* @param in
* @param type
* @param executor
* @return java.util.concurrent.Future&lt;A extends ASObject>
*/
public <A extends ASObject>Future<A> readAs(
final String in,
final Class<? extends A> type,
ExecutorService executor) {
return executor.submit(
new Callable<A>() {
public A call() throws Exception {
return readAs(in, type);
}
}
);
}
/**
* Read the given string and return a parsed object of the given type
* @param in String
* @param type Class<? extends A>
* @return A
*/
public <A extends ASObject>A readAs(
String in,
Class<? extends A> type) {
return readAs(new StringReader(in),type);
}
/**
* Asynchronously read the given string
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;ASObject>
*/
public Future<ASObject> read(String in, ExecutorService executor) {
return read(new StringReader(in), executor);
}
/**
* Read the given string
* @param in String
* @return ASObject
*/
public ASObject read(String in) {
return read(new StringReader(in));
}
/**
* Asynchronously read the given inputstream
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;ASObject>
*/
public Future<ASObject> read(InputStream in, ExecutorService executor) {
return readAs(in, ASObject.class, executor);
}
/**
* Asynchronously read the given reader
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;ASObject>
*/
public Future<ASObject> read(Reader in, ExecutorService executor) {
return readAs(in, ASObject.class, executor);
}
/**
* Read the given input stream.
* @param in InputStream
* @return ASObject
**/
public ASObject read(InputStream in) {
return readAs(in, ASObject.class);
}
/**
* Return the given input stream
* @param in InputStream
* @return A
*/
@SuppressWarnings("unchecked")
public <A extends ASObject>A readAs(InputStream in) {
return (A)read(in);
}
/**
* Read the given string as an Activity object
* @param in String
* @return Activity
*/
public Activity readAsActivity(String in) {
return readAsActivity(new StringReader(in));
}
/**
* Asynchronously read the given string as an Activity object
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;Activity>
*/
public Future<Activity> readAsActivity(String in, ExecutorService executor) {
return readAsActivity(new StringReader(in), executor);
}
/**
* Asynchronously read the given inputstream as an Activity object
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;Activity>
*/
public Future<Activity> readAsActivity(InputStream in, ExecutorService executor) {
return readAs(in, Activity.class, executor);
}
/**
* Asynchronously read the given reader as an Activity object
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;Activity>
*/
public Future<Activity> readAsActivity(Reader in, ExecutorService executor) {
return readAs(in, Activity.class, executor);
}
/**
* Asynchronously read the given string as a Collection object
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;Collection>
*/
public Future<Collection> readAsCollection(String in, ExecutorService executor) {
return readAsCollection(new StringReader(in), executor);
}
/**
* Asynchronously read the given input stream as a Collection object
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;Collection>
*/
public Future<Collection> readAsCollection(InputStream in, ExecutorService executor) {
return readAs(in, Collection.class, executor);
}
/**
* Asynchronously read the given reader as a Collection object
* @param in
* @param executor
* @return java.util.concurrent.Future&lt;Collection>
*/
public Future<Collection> readAsCollection(Reader in, ExecutorService executor) {
return readAs(in, Collection.class, executor);
}
/**
* Read the given inputstream as an Activity.
* @param in InputStream
* @return Activity
**/
public Activity readAsActivity(InputStream in) {
return readAs(in, Activity.class);
}
/**
* Read the given string as a Collection.
* @param in InputStream
* @return Collection
**/
public Collection readAsCollection(String in) {
return readAsCollection(new StringReader(in));
}
/**
* Read the given inputstream as a Collection.
* @param in InputStream
* @return Collection
**/
public Collection readAsCollection(InputStream in) {
return readAs(in, Collection.class);
}
/**
* Read the given reader
* @param in
* @return ASObject
*/
public ASObject read(Reader in) {
return readAs(in, ASObject.class);
}
/**
* Read the given reader as an Activity
* @param in Reader
* @return Activity
**/
public Activity readAsActivity(Reader in) {
return readAs(in, Activity.class);
}
/**
* Read the given reader as a Collection
* @param in Reader
* @return Collection
**/
public Collection readAsCollection(Reader in) {
return readAs(in, Collection.class);
}
}

View File

@ -0,0 +1,309 @@
package com.ibm.common.activitystreams;
import static com.google.common.base.Preconditions.checkArgument;
import java.io.Serializable;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.activitystreams.util.AbstractWritable;
/**
* An Activity Streams 2.0 Link Value.
*
* <p>In Actvity Streams 2.0, Link Values can take one of three possible
* forms:</p>
*
* <ul>
* <li>A String containing an absolute IRI</li>
* <li>An Activity String object</li>
* <li>An Array containing a mix of Strings or Objects</li>
* </ul>
*
* <p>For instance, the following are all valid examples of Link Values:</p>
*
* <pre>
* {
* "actor": "acct:joe@example.org"
* }
*
* {
* "actor": {
* "objectType": "person",
* "id": "acct:sally@example.org"
* }
* }
*
* {
* "actor": [
* "acct:joe@example.org",
* {
* "objectType": "person",
* "id": "acct:sally@example.org"
* }
* ]
* }
* </pre>
*
* <p>The LinkValue interface provides a minimal abstraction over these
* value options. Developers will have to check the ValueType of the LinkValue
* (or do an instanceof check) in order to determine which kind of value
* they are working with.</p>
*
* <pre>
* Activity activity = ...;
* Iterable<LinkValue> actors = activity.actor();
* for (LinkValue actor : actors) {
* switch(actor.valueType()) {
* case SIMPLE:
* SimpleLinkValue s = (SimpleLinkValue)actor;
* //...
* break;
* case OBJECT:
* ASObject obj = (ASObject)actor;
* //...
* break;
* }
* }
* </pre>
*
* <p>Methods that return Iterable<LinkValue> will never include an instance
* of ArrayLinkValue as one of the Iterable values</p>
*
* @author james
* @version $Revision: 1.0 $
*/
public interface LinkValue
extends Writable, Serializable {
/**
* Returns the LinkValue type
* @return ValueType
*/
ValueType valueType();
/**
* A "Simple Link Value" is a string with a relative or absolute
* URI or IRI value.
*/
public static final class SimpleLinkValue
extends AbstractWritable
implements LinkValue, Serializable {
/**
* Creates a new builder
* @return Builder
**/
public static Builder make() {
return new Builder();
}
/**
* Creates a new instance
* @param url String
* @return LinkValue
**/
public static LinkValue make(String url) {
return new SimpleLinkValue.Builder().url(url).get();
}
public static final class Builder
extends AbstractWritable.AbstractWritableBuilder<SimpleLinkValue,Builder> {
private String iri;
/**
* Set the url
* @param iri String
* @return Builder
**/
public Builder url(String iri) {
this.iri = iri;
return this;
}
/**
* Method get.
* @return SimpleLinkValue
* @see com.google.common.base.Supplier#get()
**/
public SimpleLinkValue get() {
return new SimpleLinkValue(this);
}
}
private final String iri;
SimpleLinkValue(SimpleLinkValue.Builder builder) {
super(builder);
this.iri = builder.iri;
}
/**
* Return the url
* @return String
*/
public String url() {
return iri;
}
public String toString() {
return iri;
}
public ValueType valueType() {
return ValueType.SIMPLE;
}
// Java Serialization Support
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private String iri;
SerializedForm(SimpleLinkValue obj) {
this.iri = obj.iri;
}
Object readResolve()
throws java.io.ObjectStreamException {
return Makers.linkValue(iri);
}
}
}
/**
* An Array Link value is a JSON Array of one or more Simple or Object
* Link Values. Array Link Values MUST NOT contain nested arrays.
*/
public static final class ArrayLinkValue
extends AbstractWritable
implements Iterable<LinkValue>, LinkValue, Serializable {
/**
* Create a new builder
* @return ArrayLinkValue.Builder
**/
public static ArrayLinkValue.Builder make() {
return new ArrayLinkValue.Builder();
}
public static class Builder
extends AbstractWritable.AbstractWritableBuilder<ArrayLinkValue, Builder> {
private final ImmutableList.Builder<LinkValue> links =
ImmutableList.builder();
/**
* Add one or more items
* @param value String
* @param values String[]
* @return Builder */
public Builder add(String value, String... values) {
if (value != null)
add(SimpleLinkValue.make(value));
if (values != null)
for (String v : values)
add(SimpleLinkValue.make(v));
return this;
}
/**
* Add one or more link values
* @param links Iterable<LinkValue>
* @return Builder */
public Builder add(Iterable<LinkValue> links) {
for (LinkValue l : links)
add(l);
return this;
}
/**
* Add one or more link values
* @param values LinkValue[]
* @return Builder */
public Builder add(LinkValue value, LinkValue... values) {
if (value != null) {
checkArgument(value.valueType() != ValueType.ARRAY);
links.add(value);
}
if (values != null)
for (LinkValue v : values) {
checkArgument(v.valueType() != ValueType.ARRAY);
links.add(v);
}
return this;
}
/**
* Add a link value
* @param value Supplier<? extends LinkValue>
* @return Builder */
public Builder add(Supplier<? extends LinkValue> value) {
LinkValue val = value.get();
checkArgument(val.valueType() != ValueType.ARRAY);
links.add(val);
return this;
}
/**
* Method get.
* @return ArrayLinkValue
* @see com.google.common.base.Supplier#get()
**/
public ArrayLinkValue get() {
return new ArrayLinkValue(this);
}
}
private final ImmutableList<LinkValue> links;
ArrayLinkValue(ArrayLinkValue.Builder builder) {
super(builder);
this.links = builder.links.build();
}
/**
* Method iterator.
* @return Iterator<LinkValue>
* @see java.lang.Iterable#iterator()
**/
public Iterator<LinkValue> iterator() {
return links.iterator();
}
public String toString() {
return links.toString();
}
public ValueType valueType() {
return ValueType.ARRAY;
}
// Java Serialization Support
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private ImmutableList<LinkValue> list;
SerializedForm(ArrayLinkValue obj) {
this.list = obj.links;
}
Object readResolve()
throws java.io.ObjectStreamException {
return Makers.linkValues().add(list);
}
}
}
}

View File

@ -0,0 +1,153 @@
package com.ibm.common.activitystreams;
import java.util.Map;
import static com.google.common.collect.ImmutableMap.copyOf;
import com.ibm.common.activitystreams.internal.Schema;
/**
* Utility class for creating Makers for all of the various objects.
*/
public final class Makers {
private Makers() {}
/**
* Make a new ActionsValue.Builder
* @return ParametersValue.Builder
**/
public static ActionsValue.Builder actions() {
return new ActionsValue.Builder();
}
/**
* Make a new Schema.Builder
* @return Schema.Builder
*/
public static Schema.Builder schema() {
return Schema.make();
}
/**
* Make a new IO.builder
* @return IO.Builder
**/
public static IO.Builder io() {
return IO.make();
}
/**
* Make a new Activity.Builder
* @return Activity.Builder
**/
public static Activity.Builder activity() {
return new Activity.Builder();
}
/**
* Make a new Collection.Builder
* @return Collection.Builder
**/
public static Collection.Builder collection() {
return new Collection.Builder();
}
/**
* Make a new ASObject.Builder
* @return ASObject.Builder
**/
public static ASObject.Builder object() {
return new ASObject.Builder();
}
/**
* Make a new ASObject.Builder with a specific objectType
* @param type String
* @return ASObject.Builder
**/
public static ASObject.Builder object(String type) {
return object().objectType(type);
}
/**
* Return an Object from the given Map
* @param map
* @return ASObject
*/
public static ASObject objectFrom(Map<String,?> map) {
ASObject.Builder builder = object();
for (Map.Entry<String,?> entry : copyOf(map).entrySet())
builder.set(entry.getKey(), entry.getValue());
return builder.get();
}
/**
* Make a new ASObject.Builder
* @param type TypeValue
* @return ASObject.Builder
**/
public static ASObject.Builder object(TypeValue type) {
return object().objectType(type);
}
/**
* Make a new TypeValue
* @param iri String
* @return TypeValue
**/
public static TypeValue type(String iri) {
return TypeValue.SimpleTypeValue.make(iri);
}
/**
* Make a new LinkValue
* @param iri String
* @return LinkValue
**/
public static LinkValue linkValue(String iri) {
return LinkValue.SimpleLinkValue.make(iri);
}
/**
* Make a new ArrayLinkValue.Builder
* @return LinkValue.ArrayLinkValue.Builder
**/
public static LinkValue.ArrayLinkValue.Builder linkValues() {
return LinkValue.ArrayLinkValue.make();
}
/**
* Make a new MapNLV.Builder
* @return NLV.MapNLV.Builder
**/
public static NLV.MapNLV.Builder nlv() {
return NLV.MapNLV.make();
}
/**
* Make a new SimpleNLV value
* @param val String
* @return NLV.SimpleNLV
**/
public static NLV.SimpleNLV nlv(String val) {
return NLV.SimpleNLV.make(val);
}
/**
* Make a new verb ASObject.Builder
* @param id String
* @return ASObject.Builder
*/
public static ASObject.Builder verb(String id) {
return object("verb").id(id);
}
/**
* Make a new objectType ASObject.Builder
* @param id String
* @return ASObject.Builder
*/
public static ASObject.Builder objectType(String id) {
return object("objectType").id(id);
}
}

View File

@ -0,0 +1,257 @@
package com.ibm.common.activitystreams;
import static com.google.common.collect.Maps.difference;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.ibm.common.activitystreams.util.AbstractWritable;
/**
* An Activity Streams 2.0 Natural Language Value...
*
* <p>The value is either a simple string or an object
* with multiple Language-Tag keys and values...</p>
*
* <pre>
* {
* "objectType": "note",
* "displayName": {
* "en": "My Title In English",
* "fr": "Mon titre en français"
* }
* }
* </pre>
*
* <p>
* ASObject obj = ...
* System.out.println(obj.displayNameString("en"));
* System.out.println(obj.displayNameString("fr"));
*
* NLV nlv = obj.displayName();
* switch(nlv.valueType()) {
* case SIMPLE:
* SimpleNLV s = (SimpleNLV)nlv;
* ...
* break;
* case OBJECT:
* MapNLV m = (MapNLV)nlv;
* ...
* break;
* }
* </p>
*
* @author james
* @version $Revision: 1.0 $
*/
public interface NLV
extends Writable, Serializable {
/**
* Returns the value type. Either ValueType.SIMPLE or ValueType.OBJECT
* @return ValueType
*/
ValueType valueType();
public static final class SimpleNLV
extends AbstractWritable
implements NLV, Serializable {
/**
* Create a new builder
* @return Builder */
public static Builder make() {
return new Builder();
}
/**
* Create a new instance
* @param value String
* @return SimpleNLV */
public static SimpleNLV make(String value) {
return make().value(value).get();
}
private final String val;
SimpleNLV(Builder builder) {
super(builder);
this.val = builder.val;
}
/**
* Return the value
* @return String
**/
public String value() {
return val;
}
@Override
public int hashCode() {
return Objects.hashCode(val);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleNLV other = (SimpleNLV) obj;
return Objects.equal(val, other.val);
}
public String toString() {
return val;
}
public static final class Builder
extends AbstractWritable.AbstractWritableBuilder<SimpleNLV,Builder> {
private String val;
public Builder value(String val) {
this.val = val;
return this;
}
public SimpleNLV get() {
return new SimpleNLV(this);
}
}
public ValueType valueType() {
return ValueType.SIMPLE;
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private String value;
SerializedForm(SimpleNLV obj) {
this.value = obj.val;
}
Object readResolve()
throws java.io.ObjectStreamException {
return Makers.nlv(value);
}
}
}
public static final class MapNLV
extends AbstractWritable
implements NLV, Iterable<String> {
public static Builder make() {
return new Builder();
}
private final ImmutableMap<String,String> vals;
private transient int hash = 1;
MapNLV(Builder builder) {
super(builder);
this.vals = builder.vals.build();
}
public String value(String lang) {
return vals.get(lang);
}
public boolean has(String lang) {
return vals.containsKey(lang);
}
@Override
public int hashCode() {
if (hash == 1)
hash = Objects.hashCode(vals);
return hash;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MapNLV other = (MapNLV) obj;
return
difference(vals, other.vals)
.areEqual();
}
public Iterator<String> iterator() {
return vals.keySet().iterator();
}
public static final class Builder
extends AbstractWritable.AbstractWritableBuilder<MapNLV,Builder> {
private final ImmutableMap.Builder<String,String> vals =
ImmutableMap.builder();
public Builder from(MapNLV other, String lang) {
for (String l : other)
if (!l.equalsIgnoreCase(lang))
set(l, other.value(l));
return this;
}
public Builder set(String lang, String val) {
vals.put(lang,val);
return this;
}
public MapNLV get() {
return new MapNLV(this);
}
}
public ValueType valueType() {
return ValueType.OBJECT;
}
public Map<String,String> toMap() {
return vals;
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private ImmutableMap<String,String> map;
SerializedForm(MapNLV obj) {
this.map = obj.vals;
}
Object readResolve()
throws java.io.ObjectStreamException {
NLV.MapNLV.Builder builder =
Makers.nlv();
for (Map.Entry<String,String> entry : map.entrySet())
builder.set(entry.getKey(), entry.getValue());
return builder.get();
}
}
}
}

View File

@ -0,0 +1,140 @@
package com.ibm.common.activitystreams;
import java.io.Serializable;
import com.ibm.common.activitystreams.util.AbstractWritable;
/**
* In Activity Streams 2.0, the "objectType" and "verb" properties,
* as well as several other properties, are defined as "Type Values".
* A "Type Value" can be either a simple token string, an absolute
* IRI string, or an ASObject.
*
* <pre>
* {
* "verb": "post"
* }
*
* {
* "verb": "urn:example:verbs:foo"
* }
*
* {
* "verb": {
* "id": "urn:example:verbs:foo",
* "displayName": "Foo"
* }
* }
* </pre>
*
* <p>The TypeValue interface provides a minimal abstraction
* over these possible values. Developers should check valueType
* to determine which type of TypeValue they are working with.</p>
*
* <pre>
* Activity activity = ...
* TypeValue tv = activity.verb();
*
* System.out.println(tv.id());
*
* switch(tv.valueType()) {
* case SIMPLE:
* SimpleTypeValue s = (SimpleTypeValue)tv;
* ...
* break;
* case OBJECT:
* ASObject o (ASObject)tv;
* ...
* break;
* }
* </pre>
*
* @author james
* @version $Revision: 1.0 $
*/
public interface TypeValue
extends Writable, Serializable {
/**
* Return the type value identifier
* @return String
*/
String id();
ValueType valueType();
public static final class SimpleTypeValue
extends AbstractWritable
implements TypeValue, Serializable {
public static Builder make() {
return new SimpleTypeValue.Builder();
}
public static TypeValue make(String url) {
return make().url(url).get();
}
public static final class Builder
extends AbstractWritable.AbstractWritableBuilder<SimpleTypeValue,Builder> {
private String iri;
/**
* Set the url
* @param iri String
* @return Builder
**/
public Builder url(String iri) {
this.iri = iri;
return this;
}
public SimpleTypeValue get() {
return new SimpleTypeValue(this);
}
}
private final String iri;
SimpleTypeValue(SimpleTypeValue.Builder builder) {
super(builder);
this.iri = builder.iri;
}
/**
* Return the type value identifier
* @return String
* @see com.ibm.common.activitystreams.TypeValue#id() */
public String id() {
return iri;
}
public String toString() {
return iri;
}
public ValueType valueType() {
return ValueType.SIMPLE;
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -1975376657749952999L;
private String iri;
SerializedForm(SimpleTypeValue obj) {
this.iri = obj.iri;
}
Object readResolve()
throws java.io.ObjectStreamException {
return Makers.type(iri);
}
}
}
}

View File

@ -0,0 +1,15 @@
package com.ibm.common.activitystreams;
/**
* Used for TypeValue, LinkValue and NLV interfaces to distinguish
* between the possible value options.
*
* LinkValue.valueType() can return SIMPLE, OBJECT or ARRAY
* TypeValue.valueType() can return SIMPLE or OBJECT
* NLV.valueType() can return SIMPLE or OBJECT
*/
public enum ValueType {
SIMPLE,
OBJECT,
ARRAY;
}

View File

@ -0,0 +1,76 @@
package com.ibm.common.activitystreams;
import java.io.OutputStream;
import java.io.Writer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
* Base interface for all objects that serialize to IO object instances
* @author james
* @version $Revision: 1.0 $
*/
public interface Writable {
/**
* Write the object to the output stream using the default IO instance
* @param out OutputStream
*/
void writeTo(OutputStream out);
/**
* Asynchronously write the object to the output stream using the
* default IO instance
* @param out
* @param executor
* @return Future&lt;?>
*/
Future<?> writeTo(OutputStream out, ExecutorService executor);
/**
* Write the object to the Writer using the default IO instance
* @param out Writer
*/
void writeTo(Writer out);
/**
* Asynchronously write the object to the writer using the default IO instance
* @param out
* @param executor
* @return Future&lt;?>
*/
Future<?> writeTo(Writer out, ExecutorService executor);
/**
* Write the object to the output stream using the given IO instance
* @param out OutputStream
* @param io IO
*/
void writeTo(OutputStream out, IO io);
/**
* Asynchronously write the object to the output stream using the given
* IO instance.
* @param out
* @param io
* @param executor
* @return Future&lt;?>
*/
Future<?> writeTo(OutputStream out, IO io, ExecutorService executor);
/**
* Write the object to the writer using the given IO instance
* @param out Writer
* @param io IO
*/
void writeTo(Writer out, IO io);
/**
* Asynchronously write the object to the writer using the given IO instance
* @param out
* @param io
* @param executor
* @return Future&lt;?>
*/
Future<?> writeTo(Writer out, IO io, ExecutorService executor);
}

View File

@ -0,0 +1,302 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.collect.ImmutableList.builder;
import static com.ibm.common.activitystreams.Makers.activity;
import static com.ibm.common.activitystreams.Makers.collection;
import static com.ibm.common.activitystreams.Makers.object;
import java.lang.reflect.Type;
import java.util.Map.Entry;
import com.google.common.base.Converter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.Collection;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.Makers;
import com.ibm.common.activitystreams.TypeValue;
/**
* @author james
* @version $Revision: 1.0 $
*/
public class ASObjectAdapter
extends Adapter<ASObject> {
private final Schema schema;
protected Schema schema() {
return schema;
}
/**
* Constructor for ASObjectAdapter.
* @param schema Schema
*/
protected ASObjectAdapter(Schema schema) {
this.schema = schema;
}
/**
* Method serialize.
* @param obj ASObject
* @param type Type
* @param context JsonSerializationContext
* @return JsonElement */
public final JsonElement serialize(
ASObject obj,
Type type,
JsonSerializationContext context) {
JsonObject el =
new JsonObject();
for (String key : obj) {
Object val = obj.get(key);
if (val != null) {
el.add(
key,
context.serialize(
val,
val.getClass()));
}
}
return el;
}
private static final ImmutableSet<? extends Type> knownTypes =
ImmutableSet.of(
Collection.class,
Activity.class);
protected boolean knowsType(Type type) {
return knownTypes.contains(type);
}
protected ASObject.AbstractBuilder<?,?> builderFor(Type type) {
if (type == Collection.class)
return collection();
else if (type == Activity.class)
return activity();
else return null;
}
protected Model modelFor(Type type) {
if (type == Collection.class)
return schema.forObjectClassOrType(
Collection.Builder.class,
"collection");
else if (type == Activity.class)
return schema.forObjectClassOrType(
Activity.Builder.class,
"activity");
else return null;
}
/**
* Method deserialize.
* @param element JsonElement
* @param type Type
* @param context JsonDeserializationContext
* @return ASObject
* @throws JsonParseException
* @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)
**/
public final ASObject deserialize(
JsonElement element,
Type type,
JsonDeserializationContext context)
throws JsonParseException {
JsonObject obj = (JsonObject)element;
ASObject.AbstractBuilder<?,?> builder = null;
Model propMap = null;
TypeValue tv = null;
if (knowsType(type)) {
builder = builderFor(type);
propMap = modelFor(type);
} else {
if (obj.has("objectType")) {
tv = context.deserialize(
obj.get("objectType"),
TypeValue.class);
@SuppressWarnings("rawtypes")
Class<? extends ASObject.AbstractBuilder> _class =
schema.builderForObjectTypeOrClass(tv.id(), (Class)type);
if (_class != null) {
propMap = schema.forObjectClassOrType(_class, tv.id());
if (!_class.isInterface()) {
try {
builder = _class.getConstructor(String.class).newInstance(tv.id());
} catch (Throwable t) {
try {
builder = _class.newInstance();
builder.set("objectType", tv);
} catch (Throwable t2) {
builder = Makers.object(tv);
}
}
} else
builder = Makers.object(tv);
} else {
builder = Makers.object(tv);
propMap = schema.forObjectClassOrType(
ASObject.Builder.class, tv.id());
}
} else {
if (obj.has("verb") &&
(obj.has("actor") ||
obj.has("object") ||
obj.has("target"))) {
builder = activity();
propMap = schema.forObjectClassOrType(
Activity.Builder.class, "activity");
} else if (obj.has("items")) {
builder = collection();
propMap = schema.forObjectClassOrType(
Collection.Builder.class,
"collection");
} else {
@SuppressWarnings("rawtypes")
Class<? extends ASObject.AbstractBuilder> _class =
schema.builderFor((Class)type);
if (_class != null) {
if (!_class.isInterface()) {
try {
builder = _class.newInstance();
} catch (Throwable t) {
builder = object();
}
} else builder = object();
}
if (builder == null)
builder = object(); // anonymous
propMap = schema.forObjectClass(builder.getClass());
propMap = propMap != null ?
propMap :
schema.forObjectClass(
ASObject.Builder.class);
}
}
}
for (Entry<String,JsonElement> entry : obj.entrySet()) {
String name = entry.getKey();
if (name.equalsIgnoreCase("objectType")) continue;
Class<?> _class = propMap.get(name);
JsonElement val = entry.getValue();
if (val.isJsonPrimitive())
builder.set(
name,
_class != null ?
context.deserialize(val,_class) :
primConverter.convert(val.getAsJsonPrimitive()));
else if (val.isJsonArray())
builder.set(
name,
LinkValue.class.isAssignableFrom(_class!=null?_class:Object.class) ?
context.deserialize(val, LinkValue.class) :
convert(
val.getAsJsonArray(),
_class,
context,
builder()));
else if (val.isJsonObject())
builder.set(
name,
context.deserialize(
val,
propMap.has(name) ?
propMap.get(name):
ASObject.class));
}
return builder.get();
}
/**
* Method convert.
* @param arr JsonArray
* @param _class Class<?>
* @param context JsonDeserializationContext
* @param list ImmutableList.Builder<Object>
* @return ImmutableList<Object>
*/
private ImmutableList<Object> convert(
JsonArray arr,
Class<?> _class,
JsonDeserializationContext context,
ImmutableList.Builder<Object> list) {
processArray(arr, _class, context, list);
return list.build();
}
/**
* Method processArray.
* @param arr JsonArray
* @param _class Class<?>
* @param context JsonDeserializationContext
* @param list ImmutableList.Builder<Object>
*/
private void processArray(
JsonArray arr,
Class<?> _class,
JsonDeserializationContext context,
ImmutableList.Builder<Object> list) {
for (JsonElement mem : arr) {
if (mem.isJsonPrimitive())
list.add(
_class != null ?
context.deserialize(mem,_class) :
primConverter.convert(
mem.getAsJsonPrimitive()));
else if (mem.isJsonObject())
list.add(
context.deserialize(
mem,
_class != null ?
_class :
ASObject.class));
else if (mem.isJsonArray())
list.add(
convert(
mem.getAsJsonArray(),
_class,
context,
builder()));
}
}
public static final Converter<JsonPrimitive,Object> primConverter =
new Converter<JsonPrimitive,Object>() {
@Override
protected JsonPrimitive doBackward(Object a) {
if (a instanceof Boolean)
return new JsonPrimitive((Boolean)a);
else if (a instanceof Number)
return new JsonPrimitive((Number)a);
else
return new JsonPrimitive(a.toString());
}
@Override
protected Object doForward(JsonPrimitive b) {
if (b.isBoolean())
return b.getAsBoolean();
else if (b.isNumber())
return b.getAsNumber();
else
return b.getAsString();
}
};
}

View File

@ -0,0 +1,13 @@
package com.ibm.common.activitystreams.internal;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonSerializer;
/**
* @author james
* @version $Revision: 1.0 $
*/
public abstract class Adapter<T>
implements JsonSerializer<T>, JsonDeserializer<T> {
}

View File

@ -0,0 +1,315 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.getFirst;
import static com.google.common.collect.Iterables.size;
import static com.ibm.common.activitystreams.Makers.actions;
import static com.ibm.common.activitystreams.Makers.linkValues;
import static com.ibm.common.activitystreams.internal.ASObjectAdapter.primConverter;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Map;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.joda.time.format.ISODateTimeFormat;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.collect.BoundType;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Range;
import com.google.common.collect.Table;
import com.google.common.net.MediaType;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.internal.LazilyParsedNumber;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.ActionsValue;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.util.AbstractDictionaryObjectAdapter;
/**
* @author james
* @version $Revision: 1.0 $
*/
final class Adapters {
private Adapters() {}
/**
* Method forEnum.
* @param _enumClass Class<E>
* @return EnumAdapter<E>
*/
static <E extends Enum<E>>EnumAdapter<E> forEnum(Class<E> _enumClass) {
return new EnumAdapter<E>(_enumClass);
}
/**
* Method forEnum.
* @param _enumClass Class<E>
* @param or E
* @return EnumAdapter<E>
*/
static <E extends Enum<E>>EnumAdapter<E> forEnum(Class<E> _enumClass, E or) {
return new EnumAdapter<E>(_enumClass,or);
}
static final Adapter<com.ibm.common.activitystreams.NLV> NLV =
new NaturalLanguageValueAdapter();
static final Adapter<ActionsValue> ACTIONS =
new AbstractDictionaryObjectAdapter
<LinkValue,
ActionsValue,
ActionsValue.Builder>(LinkValue.class) {
public JsonElement serialize(
ActionsValue actions,
Type type,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
for (String verb : actions) {
Iterable<LinkValue> links =
actions.get(verb);
obj.add(
verb,
context.serialize(
size(links) == 1 ? // if there's only one, serialize just 1
getFirst(links,null) : // otherwise, serialize the list
linkValues().add(links).get(),
LinkValue.class));
}
return obj;
}
@Override
protected ActionsValue.Builder builder() {
return actions();
}
};
static final Adapter<Iterable<?>> ITERABLE =
new Adapter<Iterable<?>>() {
public JsonElement serialize(
Iterable<?> i,
Type type,
JsonSerializationContext context) {
JsonArray ary = new JsonArray();
for (Object obj : i)
ary.add(context.serialize(obj, obj.getClass()));
return ary;
}
public Iterable<?> deserialize(JsonElement arg0, Type arg1,
JsonDeserializationContext arg2) throws JsonParseException {
return null; // handled elsewhere
}
};
static final Adapter<Date> DATE =
new SimpleAdapter<Date>() {
protected String serialize(Date t) {
return ISODateTimeFormat.dateTime().print(new DateTime(t));
}
public Date apply(String v) {
return DateTime.parse(v).toDate();
}
};
static final Adapter<DateTime> DATETIME =
new SimpleAdapter<DateTime>() {
protected String serialize(DateTime t) {
return ISODateTimeFormat.dateTime().print(t);
}
public DateTime apply(String v) {
return DateTime.parse(v);
}
};
static final Adapter<Duration> DURATION =
new SimpleAdapter<Duration>() {
public Duration apply(String v) {
return Duration.parse(v);
}
};
static final Adapter<Period> PERIOD =
new SimpleAdapter<Period>() {
public Period apply(String v) {
return Period.parse(v);
}
};
static final Adapter<Interval> INTERVAL =
new SimpleAdapter<Interval>() {
public Interval apply(String v) {
return Interval.parse(v);
}
};
static final Adapter<MediaType> MIMETYPE =
new SimpleAdapter<MediaType>() {
public MediaType apply(String v) {
return MediaType.parse(v);
}
};
static final MultimapAdapter MULTIMAP =
new MultimapAdapter();
static final Adapter<Range<?>> RANGE =
new Adapter<Range<?>>() {
public JsonElement serialize(
Range<?> src,
Type typeOfSrc,
JsonSerializationContext context) {
JsonObject el = new JsonObject();
el.add("lower", makeBound(src.lowerBoundType(),src.lowerEndpoint(),context));
el.add("upper", makeBound(src.upperBoundType(),src.upperEndpoint(),context));
return el;
}
private JsonElement makeBound(
BoundType type,
Object val,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.add("type", context.serialize(type.name().toLowerCase()));
obj.add("endpoint", context.serialize(val));
return obj;
}
@SuppressWarnings("rawtypes")
public Range<?> deserialize(
JsonElement json,
Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(json.isJsonObject());
try {
JsonObject obj = json.getAsJsonObject();
JsonObject upper = obj.getAsJsonObject("upper");
JsonObject lower = obj.getAsJsonObject("lower");
BoundType ubt = bt(upper.getAsJsonPrimitive("type"));
BoundType lbt = bt(lower.getAsJsonPrimitive("type"));
Object ub = des(upper.get("endpoint"),context);
Object lb = des(lower.get("endpoint"),context);
return Range.range((Comparable)lb, lbt, (Comparable)ub, ubt);
} catch (Throwable t) {
throw Throwables.propagate(t);
}
}
private Object des(JsonElement val, JsonDeserializationContext context) {
if (val.isJsonArray())
return MultimapAdapter.arraydes(val.getAsJsonArray(), context);
else if (val.isJsonObject())
return context.deserialize(val, ASObject.class);
else if (val.isJsonPrimitive()) {
Object v = primConverter.convert(val.getAsJsonPrimitive());
if (v instanceof LazilyParsedNumber)
v = new LazilyParsedNumberComparable((LazilyParsedNumber) v);
return v;
}
else
return null;
}
private BoundType bt(JsonPrimitive p) {
try {
return BoundType.valueOf(p.toString());
} catch (Throwable t) {
return BoundType.CLOSED;
}
}
};
static final Adapter<Optional<?>> OPTIONAL =
new Adapter<Optional<?>>() {
public JsonElement serialize(
Optional<?> src,
Type typeOfSrc,
JsonSerializationContext context) {
return context.serialize(src.orNull());
}
public Optional<?> deserialize(
JsonElement json,
Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
return null;
}
};
static final Adapter<Table<?,?,?>> TABLE =
new Adapter<Table<?,?,?>>() {
public JsonElement serialize(
Table<?, ?, ?> src,
Type typeOfSrc,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
for (Table.Cell<?, ?, ?> cell : src.cellSet()) {
String r = cell.getRowKey().toString();
String c = cell.getColumnKey().toString();
JsonObject rowobj = null;
if (!obj.has(r)) {
rowobj = new JsonObject();
obj.add(r, rowobj);
} else {
rowobj = obj.getAsJsonObject(r);
}
Object val = cell.getValue();
if (val != null)
rowobj.add(c, context.serialize(val,val.getClass()));
}
return obj;
}
public Table<?, ?, ?> deserialize(
JsonElement json,
Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
ImmutableTable.Builder<String,String,Object> table =
ImmutableTable.builder();
checkArgument(json.isJsonObject());
JsonObject obj = json.getAsJsonObject();
for (Map.Entry<String,JsonElement> rowentry : obj.entrySet()) {
String row = rowentry.getKey();
JsonElement cell = rowentry.getValue();
checkArgument(cell.isJsonObject());
for (Map.Entry<String,JsonElement> cellentry : cell.getAsJsonObject().entrySet()) {
String ckey = cellentry.getKey();
JsonElement val = cellentry.getValue();
Object desval = null;
if (val.isJsonArray())
desval = MultimapAdapter.arraydes(val.getAsJsonArray(),context);
else if (val.isJsonObject())
desval = context.deserialize(val, ASObject.class);
else if (val.isJsonPrimitive())
desval = primConverter.convert(val.getAsJsonPrimitive());
if (desval != null)
table.put(row,ckey,desval);
}
}
return table.build();
}
};
}

View File

@ -0,0 +1,107 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.base.Enums.stringConverter;
import static com.google.common.base.Preconditions.checkArgument;
import static com.ibm.common.activitystreams.util.Converters.stringConverter;
import static com.ibm.common.activitystreams.util.Converters.toLowerConverter;
import static com.ibm.common.activitystreams.util.Converters.toUpperConverter;
import java.lang.reflect.Type;
import com.google.common.base.Converter;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class EnumAdapter<E extends Enum<E>>
extends Adapter<E> {
protected static final Converter<String,String> toLower =
toLowerConverter();
protected static final Converter<String,String> toUpper =
toUpperConverter();
private final Converter<String,E> des;
private final Converter<E,String> ser;
/**
* Constructor for EnumAdapter.
* @param _enumClass Class<E>
*/
public EnumAdapter(Class<E> _enumClass) {
this(_enumClass, stringConverter(_enumClass));
}
/**
* Constructor for EnumAdapter
* @param _enumClass Class<E>
* @param or E
*/
public EnumAdapter(Class<E> _enumClass, E or) {
this(_enumClass, stringConverter(_enumClass,or));
}
/**
* Constructor for EnumAdapter.
* @param _enumClass Class<E>
* @param c Converter<String,E>
*/
public EnumAdapter(
Class<E> _enumClass,
Converter<String,E> c) {
super();
this.des = toUpper.andThen(c);
this.ser = c.reverse().andThen(toLower);
}
/**
* Method serialize.
* @param src E
* @param typeOfSrc Type
* @param context JsonSerializationContext
* @return JsonElement
*/
public JsonElement serialize(
E src,
Type typeOfSrc,
JsonSerializationContext context) {
return context.serialize(ser.convert(src));
}
/**
* Method deserialize.
* @param json JsonElement
* @param typeOfT Type
* @param context JsonDeserializationContext
* @return E
* @throws JsonParseException
* @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)
*/
public E deserialize(
JsonElement json,
Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(json.isJsonPrimitive());
JsonPrimitive jp = json.getAsJsonPrimitive();
checkArgument(jp.isString());
return des.convert(jp.getAsString());
}
/**
* Method convert.
* @param s String
* @return E
*/
protected E convert(String s) {
return des.convert(s);
}
}

View File

@ -0,0 +1,320 @@
package com.ibm.common.activitystreams.internal;
import static com.google.gson.internal.bind.TypeAdapters.NUMBER;
import static com.ibm.common.activitystreams.internal.Adapters.DATE;
import static com.ibm.common.activitystreams.internal.Adapters.DATETIME;
import static com.ibm.common.activitystreams.internal.Adapters.NLV;
import static com.ibm.common.activitystreams.internal.Adapters.TABLE;
import static com.ibm.common.activitystreams.internal.Adapters.OPTIONAL;
import static com.ibm.common.activitystreams.internal.Adapters.ACTIONS;
import static com.ibm.common.activitystreams.internal.Adapters.DURATION;
import static com.ibm.common.activitystreams.internal.Adapters.INTERVAL;
import static com.ibm.common.activitystreams.internal.Adapters.ITERABLE;
import static com.ibm.common.activitystreams.internal.Adapters.MIMETYPE;
import static com.ibm.common.activitystreams.internal.Adapters.MULTIMAP;
import static com.ibm.common.activitystreams.internal.Adapters.RANGE;
import static com.ibm.common.activitystreams.internal.Adapters.PERIOD;
import static com.ibm.common.activitystreams.internal.Adapters.forEnum;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.ReadableDuration;
import org.joda.time.ReadableInterval;
import org.joda.time.ReadablePeriod;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Range;
import com.google.common.collect.Table;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.LazilyParsedNumber;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.ActionsValue;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.Collection;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.NLV;
import com.ibm.common.activitystreams.TypeValue;
import com.ibm.common.activitystreams.Writable;
import com.ibm.common.activitystreams.util.TypeValueResolver;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class GsonWrapper {
/**
* Method make.
* @return Builder */
public static final Builder make() {
return new Builder();
}
/**
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
implements Supplier<GsonWrapper> {
private String charset = "UTF-8";
private boolean pretty;
private Schema schema = null; // default
private ImmutableList.Builder<AdapterEntry<?>> adapters =
ImmutableList.builder();
private Function<TypeValue,TypeValue> typeValueResolver =
TypeValueResolver.DEFAULT_INSTANCE;
public Builder typeValueResolver(Function<TypeValue,TypeValue> resolver) {
this.typeValueResolver = resolver;
return this;
}
/**
* Method charset.
* @param charset String
* @return Builder */
public Builder charset(String charset) {
this.charset = charset;
return this;
}
/**
* Method schema.
* @param schema Schema
* @return Builder */
public Builder schema(Schema schema) {
this.schema = schema;
return this;
}
/**
* Method adapter.
* @param type Class<? extends T>
* @param adapter Adapter<T>
* @return Builder */
public <T>Builder adapter(
Class<? extends T> type,
Adapter<T> adapter) {
return adapter(type,adapter,false);
}
/**
* Method adapter.
* @param type Class<? extends T>
* @param adapter Adapter<T>
* @param hier boolean
* @return Builder */
public <T>Builder adapter(
Class<? extends T> type,
Adapter<T> adapter,
boolean hier) {
adapters.add(new AdapterEntry<T>(type,adapter,hier));
return this;
}
/**
* Method prettyPrint.
* @param on boolean
* @return Builder */
public Builder prettyPrint(boolean on) {
this.pretty = on;
return this;
}
/**
* Method prettyPrint.
* @return Builder */
public Builder prettyPrint() {
return prettyPrint(true);
}
/**
* Method get.
* @return GsonWrapper * @see com.google.common.base.Supplier#get() */
public GsonWrapper get() {
return new GsonWrapper(this);
}
}
/**
* @author james
* @version $Revision: 1.0 $
*/
private final static class AdapterEntry<T> {
private final Class<? extends T> type;
private final Adapter<T> adapter;
private final boolean hier;
/**
* Constructor for AdapterEntry.
* @param type Class<? extends T>
* @param adapter Adapter<T>
* @param hier boolean
*/
AdapterEntry(
Class<? extends T> type,
Adapter<T> adapter,
boolean hier) {
this.type = type;
this.adapter = adapter;
this.hier = hier;
}
}
private final Gson gson;
private final String charset;
/**
* Constructor for GsonWrapper.
* @param builder Builder
*/
protected GsonWrapper(Builder builder) {
Schema schema =
builder.schema != null ?
builder.schema :
Schema.make().get();
ASObjectAdapter base =
new ASObjectAdapter(schema);
GsonBuilder b = initGsonBuilder(builder,schema,base);
for (AdapterEntry<?> entry : builder.adapters.build()) {
if (entry.hier)
b.registerTypeHierarchyAdapter(
entry.type,
entry.adapter!=null ?
entry.adapter : base);
else
b.registerTypeAdapter(
entry.type,
entry.adapter!=null ?
entry.adapter:base);
}
if (builder.pretty)
b.setPrettyPrinting();
this.gson = b.create();
this.charset = builder.charset;
}
/**
* Method initGsonBuilder.
* @param builder Builder
* @return GsonBuilder */
private static GsonBuilder initGsonBuilder(
Builder builder,
Schema schema,
ASObjectAdapter base) {
return new GsonBuilder()
.registerTypeHierarchyAdapter(TypeValue.class, new TypeValueAdapter(schema, builder.typeValueResolver))
.registerTypeHierarchyAdapter(LinkValue.class, new LinkValueAdapter(schema))
.registerTypeHierarchyAdapter(NLV.class, NLV)
.registerTypeHierarchyAdapter(Iterable.class, ITERABLE)
.registerTypeHierarchyAdapter(ActionsValue.class, ACTIONS)
.registerTypeHierarchyAdapter(Optional.class, OPTIONAL)
.registerTypeHierarchyAdapter(Range.class, RANGE)
.registerTypeHierarchyAdapter(Table.class, TABLE)
.registerTypeHierarchyAdapter(LazilyParsedNumber.class, NUMBER)
.registerTypeHierarchyAdapter(LazilyParsedNumberComparable.class, NUMBER)
.registerTypeHierarchyAdapter(ASObject.class, base)
.registerTypeHierarchyAdapter(Collection.class, base)
.registerTypeHierarchyAdapter(Activity.class, base)
.registerTypeHierarchyAdapter(ReadableDuration.class, DURATION)
.registerTypeHierarchyAdapter(ReadablePeriod.class, PERIOD)
.registerTypeHierarchyAdapter(ReadableInterval.class, INTERVAL)
.registerTypeAdapter(
Activity.Status.class,
forEnum(
Activity.Status.class,
Activity.Status.OTHER))
.registerTypeAdapter(Date.class, DATE)
.registerTypeAdapter(DateTime.class, DATETIME)
.registerTypeAdapter(MediaType.class, MIMETYPE)
.registerTypeHierarchyAdapter(Multimap.class, MULTIMAP)
;
}
/**
* Method write.
* @param w Writable
* @param out OutputStream
*/
public void write(Writable w, OutputStream out) {
try {
OutputStreamWriter wout =
new OutputStreamWriter(out, charset);
gson.toJson(w,wout);
wout.flush();
} catch (Throwable t) {
throw Throwables.propagate(t);
}
}
/**
* Method write.
* @param w Writable
* @param out Writer
*/
public void write(Writable w, Writer out) {
gson.toJson(w,out);
}
/**
* Method write.
* @param w Writable
* @return String */
public String write(Writable w) {
StringWriter sw =
new StringWriter();
write(w,sw);
return sw.toString();
}
/**
* Method readAs.
* @param in InputStream
* @param type Class<? extends A>
* @return A */
public <A extends ASObject>A readAs(InputStream in, Class<? extends A> type) {
try {
return readAs(new InputStreamReader(in, charset), type);
} catch (Throwable t) {
throw Throwables.propagate(t);
}
}
/**
* Method readAs.
* @param in Reader
* @param type Class<? extends A>
* @return A */
public <A extends ASObject>A readAs(Reader in, Class<? extends A> type) {
return (A)gson.fromJson(in, type);
}
}

View File

@ -0,0 +1,107 @@
package com.ibm.common.activitystreams.internal;
import java.io.ObjectStreamException;
import com.google.common.primitives.Longs;
import com.google.gson.internal.LazilyParsedNumber;
/**
*/
final class LazilyParsedNumberComparable
extends Number
implements Comparable<Number> {
private static final long serialVersionUID = 761729254455440231L;
private final LazilyParsedNumber inner;
/**
* Constructor for LazilyParsedNumberComparable.
* @param inner LazilyParsedNumber
*/
public LazilyParsedNumberComparable(LazilyParsedNumber inner) {
this.inner = inner;
}
/**
* Method compareTo.
* @param o Number
* @return int
*/
public int compareTo(Number o) {
return Longs.compare(inner.longValue(), o.longValue());
}
/**
* Method doubleValue.
* @return double
*/
public double doubleValue() {
return inner.doubleValue();
}
/**
* Method floatValue.
* @return float
*/
public float floatValue() {
return inner.floatValue();
}
/**
* Method intValue.
* @return int
*/
public int intValue() {
return inner.intValue();
}
/**
* Method longValue.
* @return long
*/
public long longValue() {
return inner.longValue();
}
/**
* Method byteValue.
* @return byte
*/
public byte byteValue() {
return inner.byteValue();
}
/**
* Method shortValue.
* @return short
*/
public short shortValue() {
return inner.shortValue();
}
/**
* Method equals.
* @param obj Object
* @return boolean
*/
public boolean equals(Object obj) {
return inner.equals(obj);
}
/**
* Method hashCode.
* @return int
*/
public int hashCode() {
return inner.hashCode();
}
/**
* Method toString.
* @return String
*/
public String toString() {
return inner.toString();
}
/**
* Method writeReplace.
* @return Object
* @throws ObjectStreamException
*/
private Object writeReplace() throws ObjectStreamException {
return inner;
}
}

View File

@ -0,0 +1,115 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.ibm.common.activitystreams.Makers.linkValue;
import static com.ibm.common.activitystreams.Makers.linkValues;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.LinkValue.SimpleLinkValue;
import com.ibm.common.activitystreams.TypeValue;
/**
* @author james
* @version $Revision: 1.0 $
*/
final class LinkValueAdapter
extends Adapter<LinkValue> {
private final Schema schema;
/**
* Constructor for LinkValueAdapter.
* @param schema Schema
*/
public LinkValueAdapter(Schema schema) {
this.schema = schema;
}
/**
* Method serialize.
* @param value LinkValue
* @param type Type
* @param context JsonSerializationContext
* @return JsonElement */
public JsonElement serialize(
LinkValue value,
Type type,
JsonSerializationContext context) {
switch(value.valueType()) {
case SIMPLE:
LinkValue.SimpleLinkValue simple = (SimpleLinkValue) value;
return context.serialize(simple.url(), String.class);
case ARRAY:
return context.serialize(value, Iterable.class);
case OBJECT:
return context.serialize(value, ASObject.class);
default:
throw new IllegalArgumentException();
}
}
/**
* Method deserialize.
* @param el JsonElement
* @param type Type
* @param context JsonDeserializationContext
* @return LinkValue * @throws JsonParseException * @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext) */
public LinkValue deserialize(
JsonElement el,
Type type,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(
el.isJsonArray() ||
el.isJsonObject() ||
el.isJsonPrimitive());
if (el.isJsonArray()) {
LinkValue.ArrayLinkValue.Builder builder =
linkValues();
for (JsonElement aryel : el.getAsJsonArray())
builder.add(
context.<LinkValue>deserialize(
aryel,
LinkValue.class));
return builder.get();
} else if (el.isJsonObject()) {
JsonObject obj = el.getAsJsonObject();
if (obj.has("objectType")) {
TypeValue tv =
context.deserialize(
obj.get("objectType"),
TypeValue.class);
Model pMap =
schema.forObjectType(tv.id());
return context.deserialize(
el,
pMap != null && pMap.type() != null ?
pMap.type() :
ASObject.class);
} else {
return context.deserialize(
el,
ASObject.class);
}
} else {
JsonPrimitive prim =
el.getAsJsonPrimitive();
checkArgument(prim.isString());
return linkValue(prim.getAsString());
}
}
}

View File

@ -0,0 +1,513 @@
/**
* IBM Activity Streams
* Author: jasnell@us.ibm.com
* License: Apache v2.0
*/
package com.ibm.common.activitystreams.internal;
import java.lang.reflect.Type;
import java.util.Map;
import org.joda.time.DateTime;
import org.joda.time.ReadableDuration;
import org.joda.time.ReadableInterval;
import org.joda.time.ReadablePeriod;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.ASObject.AbstractBuilder;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.NLV;
import com.ibm.common.activitystreams.TypeValue;
/**
* @author james
* @version $Revision: 1.0 $
*/
public final class Model {
final String parent;
final ImmutableMap<String,Type> properties;
final Type _default;
final Type _type;
final Type _builder;
private transient Schema schema;
/**
* Method schema.
* @param schema Schema
*/
protected void schema(Schema schema) {
this.schema = schema;
}
/**
* Method make.
* @return Builder */
public static Builder make() {
return make(null);
}
/**
* Method make.
* @param parent String
* @return Builder */
public static Builder make(String parent) {
return new Builder().parent(parent);
}
/**
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
implements Supplier<Model> {
Type _type;
Type _builder;
Type _default = null;
String parent = null;
final Map<String,Type> properties =
Maps.newHashMap();
Builder() {}
/**
* Constructor for Builder.
* @param template PropertyMap
*/
Builder(Model template) {
this.parent = template.parent;
this._default = template._default;
this._type = template._type;
this._builder = template._builder;
this.properties.putAll(template.properties);
}
/**
* Method withDefault.
* @param _default Class<?>
* @return Builder
**/
public Builder withDefault(Class<?> _default) {
this._default = _default;
return this;
}
/**
* Method type.
* @param _type Class<?>
* @param _builder Class<?>
* @return Builder
**/
@SuppressWarnings("unchecked")
public Builder type(
Class<?> _type, Class<?> _builder) {
this._type = (Class<? extends ASObject>) _type;
this._builder = (Class<? extends ASObject.AbstractBuilder<?, ?>>) _builder;
return this;
}
/**
* Method parent.
* @param parent String
* @return Builder
**/
public Builder parent(String parent) {
this.parent = parent;
return this;
}
/**
* Method naturalLanguageValue.
* @param name String
* @return Builder
**/
public Builder naturalLanguageValue(String name) {
return as(name, NLV.class);
}
/**
* Method naturalLanguageValue.
* @param names String[]
* @return Builder
**/
public Builder naturalLanguageValue(String... names) {
for (String name : names)
naturalLanguageValue(name);
return this;
}
/**
* Method object.
* @param name String
* @return Builder
**/
public Builder object(String name) {
return as(name, ASObject.class);
}
/**
* Method object.
* @param names String[]
* @return Builder
**/
public Builder object(String... names) {
for (String name : names)
object(name);
return this;
}
/**
* Method integer.
* @param name String
* @return Builder
**/
public Builder integer(String name) {
return as(name, Integer.class);
}
/**
* Method integer.
* @param names String[]
* @return Builder
**/
public Builder integer(String... names) {
for (String name : names)
integer(name);
return this;
}
/**
* Method doub.
* @param name String
* @return Builder
**/
public Builder doub(String name) {
return as(name, Double.class);
}
/**
* Method doub.
* @param names String[]
* @return Builder
**/
public Builder doub(String... names) {
for (String name : names)
doub(name);
return this;
}
/**
* Method doub.
* @param name String
* @return Builder
**/
public Builder floatValue(String name) {
return as(name, Float.class);
}
/**
* Method doub.
* @param names String[]
* @return Builder
**/
public Builder floatValue(String... names) {
for (String name : names)
floatValue(name);
return this;
}
/**
* Method string.
* @param name String
* @return Builder
**/
public Builder string(String name) {
return as(name, String.class);
}
/**
* Method string.
* @param names String[]
* @return Builder
**/
public Builder string(String... names) {
for (String name : names)
string(name);
return this;
}
/**
* Method linkValue.
* @param name String
* @return Builder
**/
public Builder linkValue(String name) {
return as(name, LinkValue.class);
}
/**
* Method linkValue.
* @param names String[]
* @return Builder
**/
public Builder linkValue(String... names) {
for (String name : names)
linkValue(name);
return this;
}
/**
* Method dateTime.
* @param name String
* @return Builder
**/
public Builder dateTime(String name) {
return as(name, DateTime.class);
}
/**
* Method dateTime.
* @param names String[]
* @return Builder
**/
public Builder dateTime(String... names) {
for (String name : names)
dateTime(name);
return this;
}
/**
* Method duration.
* @param name String
* @return Builder
*/
public Builder duration(String name) {
return as(name, ReadableDuration.class);
}
/**
* Method duration.
* @param names String[]
* @return Builder
*/
public Builder duration(String... names) {
for (String name : names)
duration(name);
return this;
}
/**
* Method period.
* @param name String
* @return Builder
*/
public Builder period(String name) {
return as (name, ReadablePeriod.class);
}
/**
* Method period.
* @param names String[]
* @return Builder
*/
public Builder period(String... names) {
for (String name: names)
period(name);
return this;
}
/**
* Method interval.
* @param name String
* @return Builder
*/
public Builder interval(String name) {
return as(name, ReadableInterval.class);
}
/**
* Method interval.
* @param names String[]
* @return Builder
*/
public Builder interval(String... names) {
for (String name: names)
interval(name);
return this;
}
/**
* Method typeValue.
* @param name String
* @return Builder */
public Builder typeValue(String name) {
return as(name, TypeValue.class);
}
/**
* Method typeValue.
* @param names String[]
* @return Builder */
public Builder typeValue(String... names) {
for (String name : names)
typeValue(name);
return this;
}
/**
* Method as.
* @param name String
* @param _class Class<?>
* @return Builder */
public Builder as(String name, Class<?> _class) {
this.properties.put(name,_class);
return this;
}
/**
* Method get.
* @return PropertyMap * @see com.google.common.base.Supplier#get() */
public Model get() {
return new Model(this);
}
}
/**
* Constructor for PropertyMap.
* @param builder Builder
*/
Model(Builder builder) {
this.parent = builder.parent;
this.properties = ImmutableMap.copyOf(builder.properties);
this._default = builder._default;
this._type = builder._type;
this._builder = builder._builder;
}
/**
* Method parentPropertyMap.
* @return PropertyMap */
protected Model parentPropertyMap() {
if (schema == null)
return null;
if (parent == null)
return null;
return schema.forObjectClassOrType(
ASObject.Builder.class,
parent.equals("object") ? null : parent);
}
/**
* Method get.
* @param name String
* @return Class<?> */
@SuppressWarnings("unchecked")
public <T extends Type>T get(String name) {
Model parent = parentPropertyMap();
return (T)(properties.containsKey(name) ?
properties.get(name) :
parent != null && _default == null ?
parent.get(name) : _default);
}
/**
* Method containsKey.
* @param name String
* @return boolean */
public boolean has(String name) {
Model parent = parentPropertyMap();
return properties.containsKey(name) ?
true : parent != null ?
parent.has(name) : false;
}
/**
* Method type.
* @return Class<? extends ASObject> */
@SuppressWarnings("unchecked")
public Class<? extends ASObject> type() {
return (Class<? extends ASObject>) _type;
}
/**
* Method builder.
* @return Class<? extends ASObject.AbstractBuilder<?,?>> */
@SuppressWarnings("unchecked")
public Class<? extends ASObject.AbstractBuilder<?,?>> builder() {
return (Class<? extends AbstractBuilder<?, ?>>) _builder;
}
/**
* Method toString.
* @return String */
public String toString() {
return Objects.toStringHelper(Model.class)
.omitNullValues()
.add("Parent", parent)
.add("Properties", properties)
.toString();
}
/**
* Method template.
* @return Builder */
public Builder template() {
return new Builder(this);
}
/**
* Method template.
* @param _type Class<? extends B>
* @param _builder Class<? extends X>
* @return PropertyMap */
public <B extends ASObject, X extends ASObject.AbstractBuilder<B,X>> Model template(
Class<? extends B> _type, Class<? extends X> _builder) {
return template().type(_type,_builder).get();
}
/**
* Method set.
* @param name String
* @param type Class<?>
* @return PropertyMap */
public Model set(String name, Class<?> type) {
return template()
.as(name, type)
.get();
}
/**
* Method set.
* @param map Map<String,Class<?>>
* @return PropertyMap */
public Model set(Map<String,Class<?>> map) {
Builder builder = template();
for (Map.Entry<String,Class<?>> entry : map.entrySet())
builder.as(entry.getKey(),entry.getValue());
return builder.get();
}
}

View File

@ -0,0 +1,122 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.collect.Iterables.getFirst;
import static com.google.common.collect.Iterables.size;
import static com.ibm.common.activitystreams.internal.ASObjectAdapter.primConverter;
import java.lang.reflect.Type;
import java.util.Map;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.ASObject;
/**
* @author james
* @version $Revision: 1.0 $
*/
@SuppressWarnings({"rawtypes","unchecked"})
final class MultimapAdapter
extends Adapter<Multimap> {
/**
* Method getAdaptedClass.
* @return Class<Multimap> */
public Class<Multimap> getAdaptedClass() {
return Multimap.class;
}
/**
* Method serialize.
* @param src Multimap
* @param typeOfSrc Type
* @param context JsonSerializationContext
* @return JsonElement */
public JsonElement serialize(
Multimap src,
Type typeOfSrc,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
for (Object key : src.keySet()) {
Iterable<Object> vals = src.get(key);
if (size(vals) == 1) {
Object f = getFirst(vals, null);
if (f != null)
obj.add(key.toString(), context.serialize(f, f.getClass()));
} else {
obj.add(key.toString(), context.serialize(vals, Iterable.class));
}
}
return obj;
}
/**
* Method arraydes.
* @param array JsonArray
* @param context JsonDeserializationContext
* @return ImmutableList<Object> */
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, ASObject.class));
else if (child.isJsonPrimitive())
builder.add(primConverter.convert(child.getAsJsonPrimitive()));
return builder.build();
}
/**
* Method deserialize.
* @param json JsonElement
* @param typeOfT Type
* @param context JsonDeserializationContext
* @return Multimap * @throws JsonParseException * @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext) */
public Multimap deserialize(
JsonElement json,
Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
ImmutableMultimap.Builder mm =
ImmutableMultimap.builder();
JsonObject obj = json.getAsJsonObject();
for (Map.Entry<String,JsonElement> entry : obj.entrySet()) {
String key = entry.getKey();
JsonElement val = entry.getValue();
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, ASObject.class));
else if (el.isJsonPrimitive())
mm.put(key,primConverter.convert(el.getAsJsonPrimitive()));
}
} else if (val.isJsonObject()) {
mm.put(key, context.deserialize(val, ASObject.class));
} else if (val.isJsonPrimitive()) {
mm.put(key, primConverter.convert(val.getAsJsonPrimitive()));
}
}
return mm.build();
}
}

View File

@ -0,0 +1,95 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.base.Preconditions.checkArgument;
import java.lang.reflect.Type;
import java.util.Map.Entry;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.NLV;
import com.ibm.common.activitystreams.NLV.MapNLV;
/**
* @author james
* @version $Revision: 1.0 $
*/
final class NaturalLanguageValueAdapter
extends Adapter<NLV> {
/**
* Method serialize.
* @param nlv NLV
* @param type Type
* @param context JsonSerializationContext
* @return JsonElement */
public JsonElement serialize(
NLV nlv,
Type type,
JsonSerializationContext context) {
JsonElement el = null;
switch (nlv.valueType()) {
case SIMPLE:
el = context.serialize(((NLV.SimpleNLV)nlv).value());
break;
case OBJECT:
NLV.MapNLV map =
(MapNLV) nlv;
JsonObject obj = new JsonObject();
for (String lang : map)
obj.addProperty(
lang.toString(),
map.value(lang));
el = obj;
break;
default:
}
return el;
}
/**
* Method deserialize.
* @param element JsonElement
* @param type1 Type
* @param context JsonDeserializationContext
* @return NLV * @throws JsonParseException * @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext) */
public NLV deserialize(
JsonElement element,
Type type1,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(
element.isJsonPrimitive() ||
element.isJsonObject());
if (element.isJsonPrimitive()) {
JsonPrimitive prim =
element.getAsJsonPrimitive();
checkArgument(prim.isString());
return NLV.SimpleNLV.make(
prim.getAsString());
} else {
try {
JsonObject obj =
element.getAsJsonObject();
NLV.MapNLV.Builder builder =
NLV.MapNLV.make();
for (Entry<String,JsonElement> entry : obj.entrySet())
builder.set(
entry.getKey(),
entry.getValue().getAsString());
return builder.get();
} catch (Throwable t) {
throw new IllegalArgumentException();
}
}
}
}

View File

@ -0,0 +1,419 @@
/**
* IBM Activity Streams
* Author: jasnell@us.ibm.com
* License: Apache v2.0
*/
package com.ibm.common.activitystreams.internal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.HashBiMap.create;
import static com.google.common.collect.Iterables.addAll;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import java.util.Map;
import java.util.Set;
import org.joda.time.Duration;
import com.google.common.base.Converter;
import com.google.common.base.Supplier;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.ActionsValue;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.Collection;
/**
* @TODO: The Schema mechanism needs to be revisited and reworked
* to be much more efficient.
* @author james
* @version $Revision: 1.0 $
*/
@SuppressWarnings("rawtypes")
public final class Schema {
/**
* @author james
* @version $Revision: 1.0 $
*/
public static final class Builder
implements Supplier<Schema> {
final Map<String,Model> objectTypeMap =
newHashMap();
final Map<String,Class<? extends ASObject.AbstractBuilder>> builderMap =
newHashMap();
final Map<Class<? extends ASObject.AbstractBuilder>,Model> objectClassMap =
newHashMap();
final BiMap<Class<? extends ASObject>, Class<? extends ASObject.AbstractBuilder>> classMap =
create(100);
final Set<Adapter<?>> adapters =
newHashSet();
Builder() {}
/**
* Constructor for Builder.
* @param template Schema
*/
Builder(Schema template) {
this.objectTypeMap.putAll(template.objectTypeMap);
this.builderMap.putAll(template.builderMap);
this.objectClassMap.putAll(template.objectClassMap);
this.classMap.putAll(template.classMap);
this.adapters.addAll(template.adapters);
}
/**
* Method adapter.
* @param _enumClass Class<E>
* @return Builder */
public <E extends Enum<E>>Builder adapter(
Class<E> _enumClass) {
return adapter(new EnumAdapter<E>(_enumClass));
}
/**
* Method adapter.
* @param _enumClass Class<E>
* @param c Converter<String,E>
* @return Builder */
public <E extends Enum<E>>Builder adapter(
Class<E> _enumClass,
Converter<String,E> c) {
return adapter(new EnumAdapter<E>(_enumClass,c));
}
/**
* Method adapter
* @param _enumClass Class<E>
* @param or E
* @return Builder
*/
public <E extends Enum<E>>Builder adapter(
Class<E> _enumClass, E or) {
return adapter(new EnumAdapter<E>(_enumClass,or));
}
/**
* Method adapter.
* @param adapter Adapter<?>
* @return Builder */
public Builder adapter(Adapter<?> adapter) {
this.adapters.add(adapter);
return this;
}
/**
* Method adapter.
* @param adapters Adapter<?>[]
* @return Builder */
public Builder adapter(Adapter<?>... adapters) {
if (adapters == null) return this;
for (Adapter<?> a : adapters)
adapter(a);
return this;
}
/**
* Method adapter.
* @param adapters Iterable<Adapter<?>>
* @return Builder */
public Builder adapter(Iterable<Adapter<?>> adapters) {
if (adapters == null) return this;
addAll(this.adapters, adapters);
return this;
}
/**
* Method map.
* @param objectType String
* @param propertyMap Supplier<PropertyMap>
* @return Builder */
public Builder map(String objectType, Supplier<Model> propertyMap) {
return map(objectType, propertyMap.get());
}
/**
* Method map.
* @param propertyMap Supplier<PropertyMap>
* @return Builder */
public Builder map(Supplier<Model> propertyMap) {
return map(null,propertyMap);
}
/**
* Method map.
* @param propertyMap PropertyMap
* @return Builder */
public Builder map(Model propertyMap) {
return map(null, propertyMap);
}
/**
* Method map.
* @param objectType String
* @param propertyMap PropertyMap
* @return Builder */
public Builder map(String objectType, Model propertyMap) {
checkNotNull(propertyMap);
Class<? extends ASObject.AbstractBuilder<?,?>> _builder = propertyMap.builder();
Class<? extends ASObject> _type = propertyMap.type();
if (objectType != null) objectTypeMap.put(objectType, propertyMap);
if (objectType != null && _builder != null)
builderMap.put(objectType,_builder);
if (_builder != null) objectClassMap.put(_builder, propertyMap);
if (_builder != null && _type != null)
classMap.put(_type,_builder);
return this;
}
/**
* Method get.
* @return Schema * @see com.google.common.base.Supplier#get() */
public Schema get() {
return new Schema(this);
}
}
final ImmutableMap<String,Model> objectTypeMap;
final ImmutableMap<Class<? extends ASObject.AbstractBuilder>, Model> objectClassMap;
final ImmutableMap<String,Class<? extends ASObject.AbstractBuilder>> builderMap;
final ImmutableBiMap<Class<? extends ASObject>, Class<? extends ASObject.AbstractBuilder>> classMap;
final ImmutableSet<Adapter<?>> adapters;
/**
* Constructor for Schema.
* @param builder Builder
*/
Schema(Builder builder) {
this.objectClassMap = ImmutableMap.copyOf(builder.objectClassMap);
this.objectTypeMap = ImmutableMap.copyOf(builder.objectTypeMap);
this.builderMap = ImmutableMap.copyOf(builder.builderMap);
this.adapters = ImmutableSet.copyOf(builder.adapters);
this.classMap = ImmutableBiMap.copyOf(builder.classMap);
for (Model pmap : objectTypeMap.values())
pmap.schema(this);
for (Model pmap : objectClassMap.values())
pmap.schema(this);
}
/**
* Method adapters.
* @return Iterable<Adapter<?>> */
public Iterable<Adapter<?>> adapters() {
return adapters;
}
/**
* Method builderForObjectTypeOrClass.
* @param ots String
* @param _class Class<?>
* @return Class<? extends ASObject.AbstractBuilder> */
public Class<? extends ASObject.AbstractBuilder> builderForObjectTypeOrClass(String ots, Class<?> _class) {
Class<? extends ASObject.AbstractBuilder> _builder = builderFor(ots);
return _builder != null ?
_builder : builderFor(_builder);
}
/**
* Method builderFor.
* @param _class Class<?>
* @return Class<? extends ASObject.AbstractBuilder> */
public Class<? extends ASObject.AbstractBuilder> builderFor(Class<?> _class) {
if (_class == null) return null;
return classMap.get(_class);
}
/**
* Method classFor.
* @param _builder Class<? extends ASObject.AbstractBuilder>
* @return Class<? extends ASObject> */
public Class<? extends ASObject> classFor(Class<? extends ASObject.AbstractBuilder> _builder) {
if (_builder == null) return null;
return classMap.inverse().get(_builder);
}
/**
* Method builderFor.
* @param ots String
* @return Class<? extends ASObject.AbstractBuilder> */
public Class<? extends ASObject.AbstractBuilder> builderFor(String ots) {
if (ots == null) return null;
return builderMap.get(ots);
}
/**
* Method forObjectType.
* @param objectType String
* @return PropertyMap */
public Model forObjectType(String objectType) {
return objectTypeMap.get(objectType);
}
/**
* Method forObjectClass.
* @param _class Class<? extends ASObject.AbstractBuilder>
* @return PropertyMap */
public Model forObjectClass(Class<? extends ASObject.AbstractBuilder> _class) {
return objectClassMap.get(_class);
}
/**
* Method forObjectClassOrType.
* @param _class Class<? extends ASObject.AbstractBuilder>
* @param objectType String
* @return PropertyMap */
public Model forObjectClassOrType(Class<? extends ASObject.AbstractBuilder> _class, String objectType) {
Model pm = forObjectClass(_class);
return pm != null ? pm : forObjectType(objectType);
}
/**
* Method template.
* @return Builder */
public Builder template() {
return new Builder(this);
}
/**
* Method toString.
* @return String */
public String toString() {
return toStringHelper(Schema.class)
.add("Object Types", objectTypeMap)
.add("Object Classes", objectClassMap)
.toString();
}
public final static Model object =
Model
.make()
.type(
ASObject.class,
ASObject.Builder.class)
.typeValue(
"objectType")
.linkValue(
"attachments",
"author",
"duplicates",
"icon",
"image",
"location",
"inReplyTo",
"tags",
"url",
"generator",
"provider",
"scope"
)
.dateTime(
"published",
"updated",
"startTime",
"endTime")
.naturalLanguageValue(
"summary",
"title",
"content",
"displayName")
.as("language", String.class)
.as("actions", ActionsValue.class)
.string("id", "rel", "alias")
.doub("rating")
.integer("height", "width")
.as("mediaType", MediaType.class)
.as("duration", Duration.class)
.get();
public final static Model activity =
Model
.make("object")
.type(
Activity.class,
Activity.Builder.class)
.typeValue("verb")
.linkValue(
"actor",
"participant",
"instrument",
"object",
"target",
"result",
"to",
"bto",
"cc",
"bcc")
.doub("priority")
.as("status", Activity.Status.class)
.get();
public final static Model collection =
Model
.make("object")
.type(
Collection.class,
Collection.Builder.class)
.dateTime(
"itemsBefore",
"itemsAfter")
.linkValue(
"first",
"last",
"prev",
"next",
"current",
"self")
.object("items")
.integer(
"startIndex",
"itemsPerPage",
"totalItems")
.get();
/**
* Method make.
* @return Schema.Builder */
public static Schema.Builder make() {
return
new Builder()
.map(null, object)
.map("activity", activity)
.map("collection", collection);
}
public static final Schema DEFAULT_SCHEMA = make().get();
}

View File

@ -0,0 +1,69 @@
package com.ibm.common.activitystreams.internal;
import java.lang.reflect.Type;
import com.google.common.base.Function;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
/**
* @author james
* @version $Revision: 1.0 $
*/
public abstract class SimpleAdapter<T>
extends Adapter<T>
implements Function<String,T> {
/**
* Method serialize.
* @param t T
* @param type Type
* @param context JsonSerializationContext
* @return JsonElement * @see com.google.gson.JsonSerializer#serialize(T, Type, JsonSerializationContext) */
public JsonElement serialize(
T t,
Type type,
JsonSerializationContext context) {
return context.serialize(serialize(t));
}
/**
* Method serialize.
* @param t T
* @return String */
protected String serialize(T t) {
return t != null ? t.toString() : null;
}
/**
* Method deserialize.
* @param v String
* @return T */
protected T deserialize(String v) {
return apply(v);
}
/**
* Method deserialize.
* @param json JsonElement
* @param type Type
* @param context JsonDeserializationContext
* @return T * @throws JsonParseException * @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext) */
public T deserialize(
JsonElement json,
Type type,
JsonDeserializationContext context)
throws JsonParseException {
return deserialize(json.getAsJsonPrimitive().getAsString());
}
}

View File

@ -0,0 +1,104 @@
package com.ibm.common.activitystreams.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.ibm.common.activitystreams.Makers.type;
import java.lang.reflect.Type;
import com.google.common.base.Function;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.TypeValue;
import com.ibm.common.activitystreams.ValueType;
/**
* @author james
* @version $Revision: 1.0 $
*/
final class TypeValueAdapter
extends Adapter<TypeValue> {
private final Schema schema;
private final Function<TypeValue,TypeValue> resolver;
/**
* Constructor for TypeValueAdapter.
* @param schema Schema
*/
public TypeValueAdapter(
Schema schema,
Function<TypeValue,TypeValue> resolver) {
this.schema = schema;
this.resolver = resolver;
}
/**
* Method serialize.
* @param value TypeValue
* @param type Type
* @param context JsonSerializationContext
* @return JsonElement */
public JsonElement serialize(
TypeValue value,
Type type,
JsonSerializationContext context) {
boolean simple = value.valueType() == ValueType.SIMPLE;
return context.serialize(
simple ? value.id() : value,
simple ? String.class : ASObject.class
);
}
/**
* Method deserialize.
* @param el JsonElement
* @param type Type
* @param context JsonDeserializationContext
* @return TypeValue * @throws JsonParseException * @see com.google.gson.JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext) */
public TypeValue deserialize(
JsonElement el,
Type type,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(
el.isJsonPrimitive() ||
el.isJsonObject());
if (el.isJsonPrimitive()) {
JsonPrimitive prim =
el.getAsJsonPrimitive();
checkArgument(prim.isString());
return resolver.apply(type(prim.getAsString()));
} else {
JsonObject obj = el.getAsJsonObject();
if (obj.has("objectType")) {
TypeValue tv =
context.deserialize(
obj.get("objectType"),
TypeValue.class);
Model pMap =
schema.forObjectType(tv.id());
return resolver.apply(
context.<ASObject>deserialize(
el,
pMap.type() != null ?
pMap.type() :
ASObject.class));
} else {
return resolver.apply(
context.<ASObject>deserialize(
el,
ASObject.class));
}
}
}
}

View File

@ -0,0 +1,284 @@
package com.ibm.common.activitystreams.util;
import static com.google.common.collect.ImmutableList.of;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.size;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Maps.difference;
import static com.ibm.common.activitystreams.Makers.linkValue;
import static com.ibm.common.activitystreams.Makers.linkValues;
import java.util.Iterator;
import java.util.Map;
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.Maps;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.ValueType;
import com.ibm.common.activitystreams.LinkValue.ArrayLinkValue;
/**
* Utility abstract base used for objects that are JSON
* dictionaries as opposed to full Activity Stream objects.
* @author james
* @version $Revision: 1.0 $
*/
public abstract class AbstractDictionaryObject<X>
extends AbstractWritable
implements Iterable<String> {
public static abstract class AbstractBuilder
<X, D extends AbstractDictionaryObject<X>, B extends AbstractBuilder<X,D,B>>
extends AbstractWritable.AbstractWritableBuilder<D,B> {
protected final Map<String, X> map =
Maps.newHashMap();
private boolean isempty = true;
/**
* Returns true if items have been added
* @return boolean
*/
public boolean notEmpty() {
return !isempty;
}
/**
* Sets an item in this dictionary object
* @param key String
* @param x X
* @return B
*/
@SuppressWarnings("unchecked")
public B set(String key, X x) {
if (x != null) {
map.put(key,x);
isempty = false;
}
return (B)this;
}
/**
* Sets an item in this dictionary object
* @param key String
* @param x Supplier<? extends X>
* @return B
*/
public B set(
String key,
Supplier<? extends X> x) {
return set(key, x.get());
}
/**
* Add a link
* @param name String
* @param url String
* @return B
**/
protected B link(String name, String url) {
return link(name, linkValue(url));
}
/**
* Add a link
* @param name String
* @param link LinkValue
* @return B
**/
@SuppressWarnings("unchecked")
protected B link(String name, LinkValue link) {
if (link == null)
return (B)this;
isempty = false;
Object obj = map.get(name);
if (link.valueType() != ValueType.ARRAY) {
if (obj instanceof LinkValue)
link =
((LinkValue) obj).valueType() == ValueType.ARRAY ?
linkValues()
.add((LinkValue.ArrayLinkValue)obj)
.add(link)
.get() :
linkValues()
.add((LinkValue)obj, link)
.get();
map.put(name, (X) link);
} else map.put(name, (X)link);
return (B)this;
}
/**
* Add a link
* @param name String
* @param link Supplier<? extends LinkValue>
* @return B
**/
public B link(String name, Supplier<? extends LinkValue> link) {
return link(name,link.get());
}
/**
* Add a link
* @param name String
* @param links Object[]
* @return B
**/
@SuppressWarnings("unchecked")
protected B link(String name, Object... links) {
if (links == null) return (B)this;
ArrayLinkValue.Builder b =
ArrayLinkValue.make();
for (Object obj : links)
_add(b, obj);
return link(name,b.get());
}
/**
* Method _add.
* @param builder ArrayLinkValue.Builder
* @param obj Object
*/
private void _add(ArrayLinkValue.Builder builder, Object obj) {
if (obj == null)
return;
else if (obj instanceof String)
builder.add((String)obj);
else if (obj instanceof ASObject)
builder.add((ASObject)obj);
else if (obj instanceof Supplier)
_add(builder,((Supplier<?>)obj).get());
else throw new IllegalArgumentException();
}
}
private final ImmutableMap<String,X> map;
private transient int hash = 1;
/**
* @param builder AbstractBuilder<X,?,?>
*/
protected AbstractDictionaryObject(AbstractBuilder<X,?,?> builder) {
super(builder);
this.map = ImmutableMap.copyOf(builder.map);
}
/**
* Method getSingle.
* @param key String
* @return X
*/
protected X getSingle(String key) {
return map.get(key);
}
/**
* Method getSingle.
* @param key String
* @param defaultValue X
* @return X
*/
protected X getSingle(String key, X defaultValue) {
X ret = getSingle(key);
return ret != null ? ret : defaultValue;
}
/**
* Method getIterable.
* @param key String
* @return Iterable<X>
*/
@SuppressWarnings("unchecked")
protected Iterable<X> getIterable(String key) {
X x = map.get(key);
return x instanceof Iterable ?
(Iterable<X>)x :
of(x);
}
/**
* Method getIterable.
* @param key String
* @param filter Predicate<X>
* @return Iterable<X>
*/
protected Iterable<X> getIterable(
String key,
Predicate<X> filter) {
return filter(getIterable(key), filter);
}
/**
* Method getIterable.
* @param key String
* @param transform Function<X,Y>
* @return Iterable<Y>
*/
protected <Y>Iterable<Y> getIterable(
String key,
Function<X,Y> transform) {
return transform(getIterable(key), transform);
}
/**
* Method getIterable.
* @param key String
* @param filter Predicate<X>
* @param transform Function<X,Y>
* @return Iterable<Y>
*/
protected <Y>Iterable<Y> getIterable(
String key,
Predicate<X> filter,
Function<X,Y> transform) {
return transform(filter(getIterable(key),filter),transform);
}
public Iterator<String> iterator() {
return map.keySet().iterator();
}
/**
* Returns true if the verb appears in the ActionsValue object
* @param key String
* @return boolean */
public boolean has(String key) {
return map.containsKey(key);
}
/**
* Returns true if the verb appears in the ActionsValue object
* and there is at least one handler in the value.
* @param key String
* @return boolean
*/
protected boolean hasAtLeastOne(String key) {
return has(key) && size(getIterable(key)) > 0;
}
public int hashCode() {
if (hash == 1)
hash = map.hashCode();
return hash;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractDictionaryObject other =
(AbstractDictionaryObject) obj;
return difference(map,other.map).areEqual();
}
}

View File

@ -0,0 +1,74 @@
package com.ibm.common.activitystreams.util;
import static com.google.common.base.Preconditions.checkArgument;
import java.lang.reflect.Type;
import java.util.Map.Entry;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.internal.Adapter;
/**
* Abstract base GSON Serializer for AbstractDictionaryObject
* instances.
* @author james
* @version $Revision: 1.0 $
*/
public abstract class AbstractDictionaryObjectAdapter
<Y,X extends AbstractDictionaryObject<Y>,
B extends AbstractDictionaryObject.AbstractBuilder<Y, X, B>>
extends Adapter<X> {
private final Class<Y> klass;
/**
* Constructor for AbstractDictionaryObjectAdapter.
* @param klass Class<Y>
*/
protected AbstractDictionaryObjectAdapter(Class<Y> klass) {
this.klass = klass;
}
public JsonElement serialize(
X x,
Type type,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
for (String key : x)
obj.add(
key,
context.serialize(
x.getSingle(key),
klass));
return obj;
}
public X deserialize(
JsonElement element,
Type type1,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(element.isJsonObject());
try {
JsonObject obj =
element.getAsJsonObject();
B builder = builder();
for (Entry<String,JsonElement> entry : obj.entrySet())
builder.set(
entry.getKey(),
context.<Y>deserialize(
entry.getValue(),
klass));
return builder.get();
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException();
}
}
protected abstract B builder();
}

View File

@ -0,0 +1,132 @@
package com.ibm.common.activitystreams.util;
import static com.ibm.common.activitystreams.IO.makeDefault;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.Writable;
/**
* Utility base class for Writable instances.
* @author james
* @version $Revision: 1.0 $
*/
public abstract class AbstractWritable
implements Writable {
public static abstract class AbstractWritableBuilder
<X extends Writable, B extends AbstractWritableBuilder<X,B>>
implements Supplier<X> {
private IO io = null;
/**
* Set the IO instance that should be used
* by default for writing instances of this
* object.
*/
@SuppressWarnings("unchecked")
public B writeUsing(IO io) {
this.io = io;
return (B)this;
}
public void writeTo(OutputStream out) {
get().writeTo(out);
}
public Future<?> writeTo(OutputStream out, ExecutorService executor) {
return get().writeTo(out,executor);
}
public void writeTo(Writer out) {
get().writeTo(out);
}
public Future<?> writeTo(Writer out, ExecutorService executor) {
return get().writeTo(out,executor);
}
public void writeTo(OutputStream out, IO io) {
get().writeTo(out,io);
}
public Future<?> writeTo(OutputStream out, IO io, ExecutorService executor) {
return get().writeTo(out, io, executor);
}
public void writeTo(Writer out, IO io) {
get().writeTo(out,io);
}
public Future<?> writeTo(Writer out, IO io, ExecutorService executor) {
return get().writeTo(out, io, executor);
}
}
private final IO io;
protected AbstractWritable(AbstractWritableBuilder<?,?> b) {
this.io = b.io != null ? b.io : makeDefault();
}
public void writeTo(OutputStream out) {
writeTo(out,io);
}
public Future<?> writeTo(OutputStream out, ExecutorService executor) {
return writeTo(out, io, executor);
}
public void writeTo(OutputStream out, IO io) {
io.write(this,out);
}
public Future<?> writeTo(OutputStream out, IO io, ExecutorService executor) {
return io.write(this,out,executor);
}
public void writeTo(Writer out) {
writeTo(out, io);
}
public Future<?> writeTo(Writer out, ExecutorService executor) {
return writeTo(out, io, executor);
}
public void writeTo(Writer out, IO io) {
io.write(this,out);
}
public Future<?> writeTo(Writer out, IO io, ExecutorService executor) {
return io.write(this, out, executor);
}
public String toString(IO io) {
StringWriter sw =
new StringWriter();
io.write(this, sw);
return sw.toString();
}
public Future<String> toString(ExecutorService executor) {
return io.write(this, executor);
}
public Future<String> toString(IO io, ExecutorService executor) {
return io.write(this, executor);
}
public String toString() {
return toString(io);
}
}

View File

@ -0,0 +1,341 @@
package com.ibm.common.activitystreams.util;
import static com.google.common.base.Enums.getIfPresent;
import static com.google.common.base.Optional.absent;
import static com.google.common.base.Optional.fromNullable;
import static com.google.common.base.Optional.of;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.joda.time.Duration.millis;
import static org.joda.time.Duration.standardDays;
import static org.joda.time.Duration.standardHours;
import static org.joda.time.Duration.standardMinutes;
import static org.joda.time.Duration.standardSeconds;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.joda.time.Period;
import com.google.common.base.Converter;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
public final class Converters {
private Converters() {}
/**
* Method toDuration.
* @param v long
* @param unit TimeUnit
* @return Duration
*/
public static Duration toDuration(long v, TimeUnit unit) {
switch(unit) {
case NANOSECONDS:
return millis(v / 1000 / 1000);
case MICROSECONDS:
return millis(v / 1000);
case MILLISECONDS:
return millis(v);
case SECONDS:
return standardSeconds(v);
case MINUTES:
return standardMinutes(v);
case HOURS:
return standardHours(v);
case DAYS:
return standardDays(v);
default:
throw new IllegalArgumentException();
}
}
/**
* Method tryParseShort.
* @param input String
* @return Short
*/
private static Short tryParseShort(String input) {
try {
return Short.parseShort(input);
} catch (Throwable t) {
return null;
}
}
/**
* Method tryParseBoolean.
* @param input String
* @return Boolean
*/
private static Boolean tryParseBoolean(String input) {
try {
return Boolean.parseBoolean(input);
} catch (Throwable t) {
return null;
}
}
/**
* Method tryParseDateTime.
* @param input String
* @return DateTime
*/
private static DateTime tryParseDateTime(String input) {
try {
return DateTime.parse(input);
} catch (Throwable t) {
return null;
}
}
/**
* Method tryParseDuration.
* @param input String
* @return Duration
*/
private static Duration tryParseDuration(String input) {
try {
return Period.parse(input).toDurationFrom(DateTime.now());
} catch (Throwable t) {
return null;
}
}
/**
* Method tryParsePeriod.
* @param input String
* @return Period
*/
private static Period tryParsePeriod(String input) {
try {
return Period.parse(input);
} catch (Throwable t) {
return null;
}
}
/**
* Method tryParseInterval.
* @param input String
* @return Interval
*/
private static Interval tryParseInterval(String input) {
try {
return Interval.parse(input);
} catch (Throwable t) {
return null;
}
}
public static final Function<Object,Optional<Interval>> toInterval =
new Function<Object,Optional<Interval>>() {
public Optional<Interval> apply(Object input) {
Optional<Interval> ret = absent();
if (input != null)
ret = input instanceof Interval ?
of((Interval)input) :
fromNullable(tryParseInterval(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Duration>> toDuration =
new Function<Object,Optional<Duration>>() {
public Optional<Duration> apply(Object input) {
Optional<Duration> ret = absent();
if (input != null)
ret = input instanceof Duration ?
of((Duration)input) :
input instanceof Number ?
of(standardSeconds(((Number)input).longValue())) :
fromNullable(tryParseDuration(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Period>> toPeriod =
new Function<Object,Optional<Period>>() {
public Optional<Period> apply(Object input) {
Optional<Period> ret = absent();
if (input != null)
ret = input instanceof Period ?
of((Period)input) :
fromNullable(tryParsePeriod(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<DateTime>> toDateTime =
new Function<Object,Optional<DateTime>>() {
public Optional<DateTime> apply(Object input) {
Optional<DateTime> ret = absent();
if (input != null)
ret = input instanceof DateTime ?
of((DateTime)input) :
input instanceof Date ?
of(new DateTime((Date)input)) :
input instanceof Number ?
of(new DateTime(((Number)input).longValue())) :
fromNullable(tryParseDateTime(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Boolean>> toBoolean =
new Function<Object,Optional<Boolean>>() {
public Optional<Boolean> apply(Object input) {
Optional<Boolean> ret = absent();
if (input != null)
ret = input instanceof Boolean ?
of((Boolean)input) :
input instanceof Number ?
of(((Number)input).intValue() != 0) :
fromNullable(tryParseBoolean(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Short>> toShort =
new Function<Object,Optional<Short>>() {
public Optional<Short> apply(Object input) {
Optional<Short> ret = absent();
if (input != null)
ret = input instanceof Number ?
of(((Number) input).shortValue()) :
fromNullable(tryParseShort(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Integer>> toInt =
new Function<Object,Optional<Integer>>() {
public Optional<Integer> apply(Object input) {
Optional<Integer> ret = absent();
if (input != null)
ret = input instanceof Number ?
of(((Number) input).intValue()) :
fromNullable(Ints.tryParse(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Long>> toLong =
new Function<Object,Optional<Long>>() {
public Optional<Long> apply(Object input) {
Optional<Long> ret = absent();
if (input != null)
ret = input instanceof Number ?
of(((Number) input).longValue()) :
fromNullable(Longs.tryParse(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Double>> toDouble =
new Function<Object,Optional<Double>>() {
public Optional<Double> apply(Object input) {
Optional<Double> ret = absent();
if (input != null)
ret = input instanceof Number ?
of(((Number) input).doubleValue()) :
fromNullable(Doubles.tryParse(input.toString()));
return ret;
}
};
public static final Function<Object,Optional<Float>> toFloat =
new Function<Object,Optional<Float>>() {
public Optional<Float> apply(Object input) {
Optional<Float> ret = absent();
if (input != null)
ret = input instanceof Number ?
of(((Number) input).floatValue()) :
fromNullable(Floats.tryParse(input.toString()));
return ret;
}
};
/**
* Method stringConverter.
* @param enumClass Class<E>
* @param or E
* @return Converter<String,E>
*/
public static <E extends Enum<E>> Converter<String,E> stringConverter(
final Class<E> enumClass,
final E or) {
return new Converter<String,E>() {
@Override
protected String doBackward(E e) {
return checkNotNull(e).name();
}
@Override
protected E doForward(String s) {
return getIfPresent(enumClass, s).or(or);
}
};
}
/**
* Method toUpperConverter.
* @return Converter<String,String>
*/
public static Converter<String,String> toUpperConverter() {
return toLowerConverter().reverse();
}
/**
* Method toUpperConverter.
* @param locale Locale
* @return Converter<String,String>
*/
public static Converter<String,String> toUpperConverter(Locale locale) {
return toLowerConverter(locale).reverse();
}
/**
* Method toLowerConverter.
* @return Converter<String,String>
*/
public static Converter<String,String> toLowerConverter() {
return toLowerConverter(Locale.getDefault());
}
/**
* Method toLowerConverter.
* @param locale Locale
* @return Converter<String,String>
*/
public static Converter<String,String> toLowerConverter(final Locale locale) {
return new Converter<String,String>() {
@Override
protected String doForward(String a) {
return a.toLowerCase(locale);
}
@Override
protected String doBackward(String b) {
return b.toUpperCase(locale);
}
};
}
}

View File

@ -0,0 +1,12 @@
package com.ibm.common.activitystreams.util;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.internal.Schema;
public interface Module {
void apply(Schema.Builder builder);
void apply(IO.Builder builder, Schema schema);
}

View File

@ -0,0 +1,31 @@
package com.ibm.common.activitystreams.util;
import com.google.common.base.Function;
import com.ibm.common.activitystreams.TypeValue;
/**
* A TypeValue resolver is used to optionally replace TypeValue
* instances. Typically, this would be used to exchange simple
* string TypeValue's with their object equivalents (if one is
* available).
*
* The replacement can be performed during parsing by setting a
* TypeValueResolver on the IO.Builder. This should be done
* carefully, however, as the resolver could negatively impact
* parsing performance depending on how it is implemented.
*
* @author james
*/
public interface TypeValueResolver
extends Function<TypeValue,TypeValue> {
public static final TypeValueResolver DEFAULT_INSTANCE =
new DefaultTypeValueResolver();
public static final class DefaultTypeValueResolver
implements TypeValueResolver {
public TypeValue apply(TypeValue tv) {
return tv;
}
}
}

View File

@ -0,0 +1,156 @@
package com.ibm.common.activitystreams.test;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.junit.Test;
import com.google.common.collect.Iterables;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.ActionsValue;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.LinkValue;
import com.ibm.common.activitystreams.LinkValue.SimpleLinkValue;
import com.ibm.common.activitystreams.Makers;
import com.ibm.common.activitystreams.NLV;
import com.ibm.common.activitystreams.NLV.MapNLV;
import com.ibm.common.activitystreams.ValueType;
public final class TestBasics {
@Test
public void testObject() {
ASObject obj =
Makers.object()
.id("urn:example:test")
.title("This is a test")
.action("like", "http://example.org/actions/like")
.get();
assertNotNull(obj);
assertEquals("urn:example:test", obj.id());
assertEquals("This is a test", obj.titleString());
ActionsValue actions = obj.actions();
Iterable<LinkValue> lvs = actions.get("like");
LinkValue lv = Iterables.getFirst(lvs, null);
assertEquals(ValueType.SIMPLE, lv.valueType());
SimpleLinkValue slv = (SimpleLinkValue) lv;
assertEquals("http://example.org/actions/like", slv.url());
}
@Test
public void testLanguageContext() {
ASObject obj =
Makers.object()
.language("en")
.title("en", "Foo")
.title("fr", "Bar")
.get();
assertEquals("Foo", obj.titleString("en"));
assertEquals("Bar", obj.titleString("fr"));
NLV nlv = obj.title();
assertEquals(ValueType.OBJECT, nlv.valueType());
MapNLV map = (MapNLV) nlv;
assertTrue(map.has("en"));
assertTrue(map.has("fr"));
assertEquals("Foo", map.value("en"));
assertEquals("Bar", map.value("fr"));
}
@Test
public void testDateTimes() {
DateTime now = DateTime.now();
ASObject obj =
Makers.object()
.updated(now)
.published(now)
.startTime(now.minus(Period.days(1)))
.endTime(now.plus(Period.days(1)))
.get();
assertNotNull(obj.updated());
assertNotNull(obj.published());
assertNotNull(obj.startTime());
assertNotNull(obj.endTime());
assertEquals(now, obj.updated());
assertEquals(now, obj.published());
assertTrue(now.isAfter(obj.startTime()));
assertTrue(now.isBefore(obj.endTime()));
}
@Test
public void testSerialization()
throws IOException,
ClassNotFoundException {
ASObject obj =
Makers.object()
.id("urn:example:test")
.title("This is a test")
.action("like", "http://example.org/actions/like")
.get();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(obj);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
obj = (ASObject) ois.readObject();
assertNotNull(obj);
assertEquals("urn:example:test", obj.id());
assertEquals("This is a test", obj.titleString());
ActionsValue actions = obj.actions();
Iterable<LinkValue> lvs = actions.get("like");
LinkValue lv = Iterables.getFirst(lvs, null);
assertEquals(ValueType.SIMPLE, lv.valueType());
SimpleLinkValue slv = (SimpleLinkValue) lv;
assertEquals("http://example.org/actions/like", slv.url());
}
@Test
public void testRoundTrip() {
Activity activity =
Makers.activity()
.verb("post")
.actor("acct:joe@example.org")
.object("http://example.org/1", "http://example.org/2")
.get();
ByteArrayOutputStream out =
new ByteArrayOutputStream();
activity.writeTo(out);
ByteArrayInputStream in =
new ByteArrayInputStream(out.toByteArray());
activity = IO.makeDefault().readAsActivity(in);
assertEquals("post", activity.verb().id());
assertEquals("acct:joe@example.org", ((SimpleLinkValue)activity.firstActor()).url());
Iterable<LinkValue> lvs = activity.object();
LinkValue lv = Iterables.get(lvs, 0);
assertEquals("http://example.org/1", ((SimpleLinkValue)lv).url());
lv = Iterables.get(lvs, 1);
assertEquals("http://example.org/2", ((SimpleLinkValue)lv).url());
}
}

View File

@ -0,0 +1,57 @@
package com.ibm.common.activitystreams.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.joda.time.DateTime;
import org.junit.Test;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.Activity;
import com.ibm.common.activitystreams.Collection;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.internal.Schema;
public final class TestIO {
@Test
public void testIO() {
IO.Builder iobuilder = IO.make();
assertNotNull(iobuilder);
IO io = iobuilder.get();
assertNotNull(io);
}
@Test
public void testIO2() {
final String in = "{\"a\":1,\"b\":2}";
final String out = "{\n \"a\": 1,\n \"b\": 2\n}";
IO io = IO.makeDefaultPrettyPrint();
assertNotNull(io);
assertTrue(io.read(in).toString(io).equals(out));
}
@Test
public void testIO3() {
final String in = "{\"a\":1,\"b\":2}";
IO io = IO.makeDefault();
assertTrue(io.read(in) instanceof ASObject);
assertTrue(io.readAs(in,Activity.class) instanceof Activity);
assertTrue(io.readAs(in,Collection.class) instanceof Collection);
assertTrue(io.readAsActivity(in) instanceof Activity);
assertTrue(io.readAsCollection(in) instanceof Collection);
}
@Test
public void testSchema() {
Schema schema =
Schema.make()
.map("foo", Schema.object.template().dateTime("bar"))
.get();
IO io = IO.make().schema(schema).get();
ASObject obj =
io.read(
"{\"objectType\":\"foo\",\"bar\":\"2013-12-12T12:12:12Z\"}");
assertTrue(obj.get("bar") instanceof DateTime);
}
}

View File

@ -0,0 +1,5 @@
{
"verb": "post",
"actor": "urn:example:person:joe",
"object": "http://example.org/posts/1"
}

144
geo/pom.xml Executable file
View File

@ -0,0 +1,144 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>activitystreams-geo</artifactId>
<name>Activity Streams 2.0 - GeoJSON</name>
<description>
A GeoJSON Implementation that can be used standalone or with the IBM
Activity Streams 2.0 Reference Implementation
</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<charset>UTF-8</charset>
<additionalparam>-XDignore.symbol.file</additionalparam>
<show>public</show>
<links>
<link>http://www.joda.org/joda-time/apidocs</link>
<link>http://docs.guava-libraries.googlecode.com/git-history/v16.0.1/javadoc/</link>
</links>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Export-Package>com.ibm.common.geojson.*</Export-Package>
<Import-Package>
com.ibm.common.activitystreams.*,
com.google.gson.*,
com.google.common.*,
org.joda.time.*
</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<versionRange>[2.3.7,)</versionRange>
<goals>
<goal>manifest</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,77 @@
package com.ibm.common.geojson;
import static com.google.common.primitives.Floats.max;
import static com.google.common.primitives.Floats.min;
import java.io.ObjectStreamException;
import com.ibm.common.activitystreams.ASObject;
/**
* Represents an Activity Streams 1.0 style position object
* @author james
* @deprecated Use Position
*/
public final class AS1Position
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<AS1Position, Builder> {
Builder() {
objectType("position");
}
public Builder latitude(float latitude) {
return set("latitude", max(0f,min(90.0f,latitude)));
}
public Builder longitude(float longitude) {
return set("longitude", max(-180.0f,min(180.0f,longitude)));
}
public Builder altitude(float altitude) {
return set("altitude", altitude);
}
@Override
public AS1Position get() {
return new AS1Position(this);
}
}
private AS1Position(Builder builder) {
super(builder);
}
public float latitude() {
return max(0f,min(90.0f,getFloat("latitude")));
}
public float longitude() {
return max(-180.0f,min(180.0f,getFloat("longitude")));
}
public float altitude() {
return getFloat("altitude");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<AS1Position> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(AS1Position obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected AS1Position.Builder builder() {
return GeoMakers.as1Position();
}
}
}

View File

@ -0,0 +1,93 @@
package com.ibm.common.geojson;
import java.io.ObjectStreamException;
import com.ibm.common.activitystreams.ASObject;
public final class Address
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Address, Builder> {
Builder() {
objectType("address");
}
public Builder formatted(String formatted) {
return set("formatted", formatted);
}
public Builder streetAddress(String streetAddress) {
return set("streetAddress", streetAddress);
}
public Builder locality(String locality) {
return set("locality", locality);
}
public Builder region(String region) {
return set("region", region);
}
public Builder postalCode(String postalCode) {
return set("postalCode", postalCode);
}
public Builder country(String country) {
return set("country", country);
}
@Override
public Address get() {
return new Address(this);
}
}
private Address(Builder builder) {
super(builder);
}
public String formatted() {
return getString("formatted");
}
public String streetAddress() {
return getString("streetAddress");
}
public String locality() {
return getString("locality");
}
public String region() {
return getString("region");
}
public String postalCode() {
return getString("postalCode");
}
public String country() {
return getString("country");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Address> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Address obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Address.Builder builder() {
return GeoMakers.address();
}
}
}

View File

@ -0,0 +1,254 @@
package com.ibm.common.geojson;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Iterator;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
public final class BoundingBox
implements Iterable<Float>, Serializable {
public static final class Builder
implements Supplier<BoundingBox> {
private final ImmutableList.Builder<Float> bounds =
ImmutableList.builder();
public Builder add(float value) {
this.bounds.add(value);
return this;
}
public Builder add(float... values) {
if (values != null)
for (float v : values)
this.bounds.add(v);
return this;
}
@Override
public BoundingBox get() {
return new BoundingBox(this);
}
}
private final ImmutableList<Float> bounds;
BoundingBox(Builder builder) {
this.bounds = builder.bounds.build();
}
@Override
public Iterator<Float> iterator() {
return bounds.iterator();
}
public String toString() {
return Objects.toStringHelper(BoundingBox.class)
.addValue(bounds)
.toString();
}
private static BoundingBox buildBoundingBox(
ImmutableSortedSet<Float> xs,
ImmutableSortedSet<Float> ys,
ImmutableSortedSet<Float> zs) {
BoundingBox.Builder bbox =
new BoundingBox.Builder()
.add(xs.first())
.add(ys.first());
if (!zs.isEmpty())
bbox.add(zs.first());
bbox.add(xs.last());
bbox.add(ys.last());
if (!zs.isEmpty())
bbox.add(zs.last());
return bbox.get();
}
protected static BoundingBox calculateBoundingBoxLineStrings(Iterable<LineString> lineStrings) {
ImmutableSortedSet.Builder<Float> xset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> yset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> zset =
ImmutableSortedSet.naturalOrder();
for (LineString ls : lineStrings) {
for (Position p : ls) {
xset.add(p.northing());
yset.add(p.easting());
if (p.hasAltitude())
zset.add(p.altitude());
}
}
return buildBoundingBox(
xset.build(),
yset.build(),
zset.build());
}
public static BoundingBox calculateBoundingBoxPolygons(Iterable<Polygon> polygons) {
ImmutableSortedSet.Builder<Float> xset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> yset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> zset =
ImmutableSortedSet.naturalOrder();
for (Polygon polygon : polygons) {
for (LineString line : polygon) {
for (Position pos : line) {
xset.add(pos.northing());
yset.add(pos.easting());
if (pos.hasAltitude())
zset.add(pos.altitude());
}
}
}
return buildBoundingBox(
xset.build(),
yset.build(),
zset.build());
}
protected static BoundingBox calculateBoundingBoxPositions(Iterable<Position> positions) {
ImmutableSortedSet.Builder<Float> xset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> yset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> zset =
ImmutableSortedSet.naturalOrder();
for (Position pos : positions) {
xset.add(pos.northing());
yset.add(pos.easting());
if (pos.hasAltitude())
zset.add(pos.altitude());
}
return buildBoundingBox(
xset.build(),
yset.build(),
zset.build());
}
protected static BoundingBox calculateBoundingBox(Position position) {
BoundingBox.Builder bbox =
new BoundingBox.Builder();
bbox.add(position.northing());
bbox.add(position.easting());
if (position.hasAltitude())
bbox.add(position.altitude());
return bbox.get();
}
private static void addValues(
ImmutableSortedSet.Builder<Float> xset,
ImmutableSortedSet.Builder<Float> yset,
ImmutableSortedSet.Builder<Float> zset,
Iterable<Position> positions) {
for (Position position : positions) {
xset.add(position.northing());
yset.add(position.easting());
if (position.hasAltitude())
zset.add(position.altitude());
}
}
private static void addValuesLineString(
ImmutableSortedSet.Builder<Float> xset,
ImmutableSortedSet.Builder<Float> yset,
ImmutableSortedSet.Builder<Float> zset,
Iterable<LineString> lines) {
for (LineString ls : lines) {
addValues(xset,yset,zset,ls);
}
}
private static void addValuesPolygon(
ImmutableSortedSet.Builder<Float> xset,
ImmutableSortedSet.Builder<Float> yset,
ImmutableSortedSet.Builder<Float> zset,
Iterable<Polygon> polygons) {
for (Polygon poly : polygons) {
addValuesLineString(xset,yset,zset,poly);
}
}
protected static BoundingBox calculateBoundingBox(Geometry<?,?> geometry) {
return calculateBoundingBoxGeometries(
ImmutableList.<Geometry<?,?>>of(geometry));
}
@SuppressWarnings("unchecked")
protected static BoundingBox calculateBoundingBoxGeometries(
Iterable<Geometry<?,?>> geometries) {
ImmutableSortedSet.Builder<Float> xset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> yset =
ImmutableSortedSet.naturalOrder();
ImmutableSortedSet.Builder<Float> zset =
ImmutableSortedSet.naturalOrder();
for (Geometry<?,?> geo : geometries) {
switch(geo.type()) {
case POINT:
Point point = (Point) geo;
Position position = Iterables.getFirst(point.coordinates(),null);
xset.add(position.northing());
yset.add(position.easting());
if (position.hasAltitude())
zset.add(position.altitude());
break;
case LINESTRING:
case MULTIPOINT:
addValues(xset,yset,zset,(Iterable<Position>)geo);
break;
case MULTILINESTRING:
case POLYGON:
addValuesLineString(xset,yset,zset,(Iterable<LineString>)geo);
break;
case MULTIPOLYGON:
addValuesPolygon(xset,yset,zset,(Iterable<Polygon>)geo);
break;
default:
break;
}
}
return buildBoundingBox(
xset.build(),
yset.build(),
zset.build());
}
protected static BoundingBox calculateBoundingBoxFeatures(Iterable<Feature> features) {
ImmutableList.Builder<Geometry<?,?>> list =
ImmutableList.builder();
for (Feature feature : features) {
Geometry<?,?> geometry = feature.geometry();
if (geometry != null)
list.add(geometry);
}
return calculateBoundingBoxGeometries(list.build());
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm implements Serializable {
private static final long serialVersionUID = -2060301713159936285L;
private ImmutableList<Float> bounds;
protected SerializedForm(BoundingBox obj) {
this.bounds = obj.bounds;
}
Object readResolve() throws ObjectStreamException {
BoundingBox.Builder builder =
new BoundingBox.Builder();
builder.bounds.addAll(bounds);
return builder.get();
}
}
}

View File

@ -0,0 +1,122 @@
package com.ibm.common.geojson;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
public final class CRS
implements Iterable<String>, Serializable {
public static final class Builder implements Supplier<CRS> {
private String type;
private ImmutableMap.Builder<String,Object> properties =
ImmutableMap.builder();
public Builder type(String type) {
this.type = type;
return this;
}
public Builder set(String name, Object value) {
this.properties.put(name,value);
return this;
}
public Builder set(Map<String,Object> properties) {
this.properties.putAll(properties);
return this;
}
public CRS get() {
return new CRS(this);
}
}
private final String type;
private final Map<String,Object> properties;
CRS(Builder builder) {
this.type = builder.type;
this.properties = builder.properties.build();
}
public String toString() {
return Objects.toStringHelper(CRS.class)
.addValue(type)
.addValue(properties)
.toString();
}
public int size() {
return properties.size();
}
public String type() {
return type;
}
public Map<String,Object> properties() {
return properties;
}
@SuppressWarnings("unchecked")
public <T>T get(String name) {
return (T)properties.get(name);
}
public <T>T get(String name, T defaultValue) {
T t = this.<T>get(name);
return t != null ? t : defaultValue;
}
public boolean has(String name) {
return properties.containsKey(name);
}
@Override
public Iterator<String> iterator() {
return properties.keySet().iterator();
}
public static final CRS named(String name) {
return new CRS.Builder()
.type("name")
.set("name",name)
.get();
}
public static final CRS linked(String href, String type) {
return new CRS.Builder()
.type("link")
.set("href", href)
.set("type", type)
.get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm implements Serializable {
private static final long serialVersionUID = -2060301713159936285L;
private String type;
private Map<String,Object> properties;
protected SerializedForm(CRS obj) {
this.type = obj.type;
this.properties = obj.properties;
}
Object readResolve() throws ObjectStreamException {
CRS.Builder builder = new CRS.Builder();
builder.type(type);
builder.properties.putAll(properties);
return builder.get();
}
}
}

View File

@ -0,0 +1,133 @@
package com.ibm.common.geojson;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBox;
import java.io.ObjectStreamException;
import java.util.Iterator;
import java.util.Map;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
public final class Feature
extends GeoObject<Feature>
implements Iterable<String> {
public static final class Builder
extends GeoObject.Builder<Feature,Builder> {
private final ImmutableMap.Builder<String,Object> properties =
ImmutableMap.builder();
public Builder() {
type(GeoObject.Type.FEATURE);
}
public Builder geometry(Geometry<?,?> geometry) {
return set("geometry", geometry);
}
public Builder geometry(Supplier<? extends Geometry<?,?>> geometry) {
return geometry(geometry.get());
}
public Builder property(String name, Object value) {
this.properties.put(name, value);
return this;
}
protected Builder properties(Map<String,Object> properties) {
properties.putAll(properties);
return this;
}
public Builder id(String id) {
return set("id", id);
}
@Override
public Feature doGet() {
set("properties", properties.build());
return new Feature(this);
}
}
Feature(Builder builder) {
super(builder);
}
public <G extends Geometry<?,?>>G geometry() {
return this.<G>get("geometry");
}
public Map<String,Object> properties() {
return this.<Map<String,Object>>get(
"properties",
ImmutableMap.<String,Object>of());
}
public String id() {
return this.<String>get("id");
}
@SuppressWarnings("unchecked")
public <T>T getProperty(String name) {
return (T) properties().get(name);
}
public <T>T getProperty(String name, T defaultValue) {
T t = this.<T>getProperty(name);
return t != null ? t : defaultValue;
}
public boolean has(String name) {
return properties().containsKey(name);
}
@Override
public Iterator<String> iterator() {
return properties().keySet().iterator();
}
@Override
protected Feature makeWithBoundingBox() {
return new Feature.Builder()
.from(this)
.properties(this.properties())
.boundingBox(
calculateBoundingBox(geometry())).get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Feature,Feature.Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(Feature obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
@Override
protected boolean handle(
Builder builder,
String key,
Object val) {
if ("properties".equals(key)) {
Map<String,Object> props = (Map<String, Object>) val;
builder.properties.putAll(props);
return true;
}
return false;
}
@Override
protected Builder builder() {
return new Feature.Builder();
}
}
}

View File

@ -0,0 +1,103 @@
package com.ibm.common.geojson;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxFeatures;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public final class FeatureCollection
extends GeoObject<FeatureCollection>
implements Iterable<Feature> {
public static final class Builder
extends GeoObject.Builder<FeatureCollection, Builder> {
private final ImmutableList.Builder<Feature> list =
ImmutableList.builder();
public Builder() {
type(GeoObject.Type.FEATURECOLLECTION);
}
public Builder add(Iterable<Feature> features) {
list.addAll(features);
return this;
}
public Builder add(Feature feature, Feature... features) {
list.add(feature);
if (features != null)
list.add(features);
return this;
}
public Builder add(Supplier<Feature> feature) {
return add(feature.get());
}
@Override
public void preGet() {
set("features", list.build());
}
@Override
public FeatureCollection doGet() {
return new FeatureCollection(this);
}
}
FeatureCollection(Builder builder) {
super(builder);
}
public Iterable<Feature> features() {
return this.<Iterable<Feature>>get(
"features",
ImmutableList.<Feature>of());
}
public int size() {
return Iterables.size(features());
}
public Feature get(int idx) {
return Iterables.get(features(),idx);
}
public Iterator<Feature> iterator() {
return features().iterator();
}
@Override
protected FeatureCollection makeWithBoundingBox() {
return new FeatureCollection.Builder()
.from(this)
.add(this)
.boundingBox(calculateBoundingBoxFeatures(this))
.get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<FeatureCollection,FeatureCollection.Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(FeatureCollection obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@Override
protected FeatureCollection.Builder builder() {
return GeoMakers.featureCollection();
}
}
}

View File

@ -0,0 +1,109 @@
package com.ibm.common.geojson;
@SuppressWarnings("deprecation")
public final class GeoMakers {
private GeoMakers() {}
public static Place.Builder place() {
return new Place.Builder();
}
/** @deprecated **/
public static AS1Position.Builder as1Position() {
return new AS1Position.Builder();
}
/** @deprecated **/
public static AS1Position as1Position(
float latitude,
float longitude,
float altitude) {
return as1Position()
.longitude(longitude)
.latitude(latitude)
.altitude(altitude)
.get();
}
/** @deprecated **/
public static AS1Position as1Position(
Position position) {
return as1Position(
position.northing(),
position.easting(),
position.altitude());
}
public static Position position(
AS1Position position) {
return position(
position.latitude(),
position.longitude(),
position.altitude());
}
public static Address.Builder address() {
return new Address.Builder();
}
public static Position position(float x, float y) {
return GeoObject.position(x,y);
}
public static Position position(float x, float y, float z) {
return GeoObject.position(x, y, z);
}
public static Point point(float x, float y) {
return point().position(x,y).get();
}
public static Point point(float x, float y, float z) {
return point().position(x, y, z).get();
}
public static Point point(Position position) {
return point().position(position).get();
}
public static Point.Builder point() {
return new Point.Builder();
}
public static MultiPoint.Builder multipoint() {
return new MultiPoint.Builder();
}
public static LineString.Builder linestring() {
return new LineString.Builder();
}
public static LineString.Builder linearRing() {
return linestring().linearRing();
}
public static Feature.Builder feature() {
return new Feature.Builder();
}
public static FeatureCollection.Builder featureCollection() {
return new FeatureCollection.Builder();
}
public static GeometryCollection.Builder geometryCollection() {
return new GeometryCollection.Builder();
}
public static MultiLineString.Builder multiLineString() {
return new MultiLineString.Builder();
}
public static MultiPolygon.Builder multiPolygon() {
return new MultiPolygon.Builder();
}
public static Polygon.Builder polygon() {
return new Polygon.Builder();
}
}

View File

@ -0,0 +1,172 @@
package com.ibm.common.geojson;
import java.io.Serializable;
import java.util.Map;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import static com.google.common.collect.ImmutableMap.copyOf;
import static com.google.common.collect.Maps.newLinkedHashMap;
@SuppressWarnings("unchecked")
public abstract class GeoObject<G extends GeoObject<G>>
implements Serializable {
private static final long serialVersionUID = 8852811044366213922L;
public static enum Type {
POINT,
MULTIPOINT,
LINESTRING,
MULTILINESTRING,
POLYGON,
MULTIPOLYGON,
GEOMETRYCOLLECTION,
FEATURE,
FEATURECOLLECTION
}
public static abstract class Builder
<G extends GeoObject<G>, B extends Builder<G,B>>
implements Supplier<G> {
protected boolean withBoundingBox = false;
protected Type type;
protected Map<String,Object> data =
newLinkedHashMap();
public B calculateBoundingBox() {
this.withBoundingBox = true;
return (B)this;
}
protected B from(GeoObject<?> geo) {
data.putAll(geo.data);
return (B)this;
}
public B type(Type type) {
this.type = type;
return (B)this;
}
public B crs(CRS crs) {
return set("crs", crs);
}
public B boundingBox(BoundingBox bbox) {
return set("bbox", bbox);
}
public B set(String name, Object val) {
if (val != null)
this.data.put(name,val);
else if (this.data.containsKey(name))
this.data.remove(name);
return (B)this;
}
public final G get() {
preGet();
G g = doGet();
return withBoundingBox ? g.withBoundingBox() : g;
}
protected void preGet() {}
protected abstract G doGet();
}
final Type type;
final Map<String,Object> data;
protected GeoObject(Builder<?,?> builder) {
this.type = builder.type;
this.data = copyOf(builder.data);
}
public Type type() {
return type;
}
public <T>T get(String name) {
return (T)data.get(name);
}
public <T>T get(String name, T defaultValue) {
T val = get(name);
return val != null ? val : defaultValue;
}
public boolean has(String name) {
return data.containsKey(name);
}
public CRS crs() {
return this.<CRS>get("crs", null);
}
public BoundingBox boundingBox() {
return this.<BoundingBox>get("bbox", null);
}
public final G withBoundingBox() {
return has("bbox") ?
(G)this : makeWithBoundingBox();
}
protected abstract G makeWithBoundingBox();
public static final Position position(float x, float y) {
return new Position.Builder()
.northing(x)
.easting(y)
.get();
}
public static final Position position(float x, float y, float z) {
return new Position.Builder()
.northing(x)
.easting(y)
.altitude(z)
.get();
}
public String toString() {
return Objects.toStringHelper(GeoObject.class)
.add("type", type)
.add("data", data)
.toString();
}
protected static abstract class AbstractSerializedForm
<G extends GeoObject<G>, B extends GeoObject.Builder<G,B>>
implements Serializable {
private static final long serialVersionUID = -1950126276150975248L;
private Type type;
private Map<String,Object> data;
AbstractSerializedForm(G obj) {
this.type = obj.type();
this.data = obj.data;
}
protected Object doReadResolve() {
B builder = builder();
builder.type(type);
for (Map.Entry<String,Object> entry : data.entrySet()) {
String key = entry.getKey();
Object val = entry.getValue();
if (!handle(builder, key,val))
builder.data.put(key,val);
}
return builder.get();
}
protected boolean handle(
B builder,
String key,
Object val) {
return false;
}
protected abstract B builder();
}
}

View File

@ -0,0 +1,48 @@
package com.ibm.common.geojson;
import com.google.common.collect.ImmutableList;
public abstract class Geometry<G extends Geometry<G,M>, M>
extends GeoObject<G>
implements Iterable<M> {
private static final long serialVersionUID = -6184360762496309625L;
protected Geometry(Builder<?,?> builder) {
super(builder);
}
public static abstract class CoordinateGeometry<G extends CoordinateGeometry<G,M,P>, M,P>
extends Geometry<G,M> {
private static final long serialVersionUID = -6502745908455054826L;
protected static abstract class Builder
<M,P,C extends CoordinateGeometry<C,M,P>, B extends Builder<M,P,C,B>>
extends GeoObject.Builder<C, B> {
protected abstract P coordinates();
public void preGet() {
set("coordinates", coordinates());
}
protected abstract C doGet();
}
protected CoordinateGeometry(Builder<M,P,?, ?> builder) {
super(builder);
}
@SuppressWarnings("unchecked")
public Iterable<M> coordinates() {
Object o = get("coordinates");
if (o instanceof Iterable)
return (Iterable<M>)o;
else
return ImmutableList.<M>of((M)o);
}
}
}

View File

@ -0,0 +1,107 @@
package com.ibm.common.geojson;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxGeometries;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public final class GeometryCollection
extends Geometry<GeometryCollection, Geometry<?,?>> {
public static final class Builder
extends GeoObject.Builder<GeometryCollection, Builder> {
private final ImmutableList.Builder<Geometry<?,?>> list =
ImmutableList.builder();
public Builder() {
type(GeoObject.Type.GEOMETRYCOLLECTION);
}
public Builder add(Geometry<?,?> geometry, Geometry<?,?>... geometries) {
list.add(geometry);
if (geometries != null)
list.add(geometries);
return this;
}
public Builder add(Iterable<Geometry<?,?>> geometries) {
list.addAll(geometries);
return this;
}
@Override
public void preGet() {
set("geometries", list.build());
}
@Override
public GeometryCollection doGet() {
return new GeometryCollection(this);
}
}
GeometryCollection(Builder builder) {
super(builder);
}
public Iterable<Geometry<?,?>> geometries() {
return this.<Iterable<Geometry<?,?>>>get(
"geometries",
ImmutableList.<Geometry<?,?>>of());
}
public int size() {
return Iterables.size(geometries());
}
@SuppressWarnings("unchecked")
public <G extends Geometry<?,?>>G get(int idx) {
return (G)Iterables.get(geometries(),idx);
}
public Iterator<Geometry<?,?>> iterator() {
return geometries().iterator();
}
@Override
public GeometryCollection makeWithBoundingBox() {
return new GeometryCollection.Builder()
.from(this)
.add(this)
.boundingBox(calculateBoundingBoxGeometries(this))
.get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<GeometryCollection,GeometryCollection.Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(GeometryCollection obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
@Override
protected boolean handle(Builder builder, String key, Object val) {
if ("geometries".equals(key)) {
Iterable<Geometry<?,?>> list = (Iterable<Geometry<?, ?>>) val;
builder.list.addAll(list);
return true;
}
return false;
}
@Override
protected GeometryCollection.Builder builder() {
return GeoMakers.geometryCollection();
}
}
}

View File

@ -0,0 +1,161 @@
package com.ibm.common.geojson;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxPositions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.getFirst;
import static com.google.common.collect.Iterables.size;
import static java.lang.String.format;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
public final class LineString
extends CoordinateGeometry<LineString,Position,Iterable<Position>> {
public static final class Builder
extends CoordinateGeometry.Builder<Position,Iterable<Position>,LineString, Builder> {
private final ImmutableList.Builder<Position> positions =
ImmutableList.builder();
private boolean ring;
private final boolean nocheck;
public Builder() {
nocheck = false;
type(Type.LINESTRING);
}
private Builder(boolean nocheck) {
this.nocheck = nocheck;
type(Type.LINESTRING);
}
public Builder linearRing() {
return linearRing(true);
}
public Builder linearRing(boolean on) {
this.ring = on;
return this;
}
public Builder add(Position position, Position... positions) {
this.positions.add(position);
if (positions != null)
for (Position pos : positions)
add(pos);
return this;
}
public Builder add(float x, float y) {
return add(GeoObject.position(x, y));
}
public Builder add(Supplier<Position> position) {
return add(position.get());
}
public Builder add(Iterable<Position> positions) {
this.positions.addAll(positions);
return this;
}
public Builder add(float x, float y, float z) {
return add(GeoObject.position(x,y,z));
}
public LineString doGet() {
return new LineString(this);
}
@Override
protected Iterable<Position> coordinates() {
return positions.build();
}
}
private final boolean ring;
protected LineString(
Builder builder) {
super(builder);
this.ring = builder.ring;
int min = ring?3:2;
checkArgument(
builder.nocheck ||
size(coordinates()) >= min,
format(
"A LineString that %s a LinearRing MUST consist of at least %d positions",
ring?"is":"is not",
min));
}
public boolean linearRing() {
return ring;
}
@Override
public Iterable<Position> coordinates() {
Iterable<Position> pos = super.coordinates();
if (!ring)
return pos;
else {
return size(pos) > 0 ?
concat(pos,ImmutableList.of(getFirst(pos,null))) :
ImmutableList.<Position>of();
}
}
@Override
public Iterator<Position> iterator() {
return coordinates().iterator();
}
@Override
public LineString makeWithBoundingBox() {
return new LineString.Builder()
.from(this)
.add(this)
.boundingBox(calculateBoundingBoxPositions(this))
.get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<LineString,Builder> {
private static final long serialVersionUID = -2060301713159936281L;
boolean ring;
protected SerializedForm(LineString obj) {
super(obj);
this.ring = obj.ring;
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
@Override
protected boolean handle(Builder builder, String key, Object val) {
if ("coordinates".equals(key)) {
Iterable<Position> list = (Iterable<Position>) val;
builder.positions.addAll(list);
return true;
}
return false;
}
@Override
protected LineString.Builder builder() {
Builder builder = new Builder(true);
builder.ring = ring;
return builder;
}
}
}

View File

@ -0,0 +1,99 @@
package com.ibm.common.geojson;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxLineStrings;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
public final class MultiLineString
extends CoordinateGeometry<MultiLineString,LineString,Iterable<LineString>> {
public static final class Builder
extends CoordinateGeometry.Builder<LineString,Iterable<LineString>, MultiLineString, Builder> {
private final ImmutableList.Builder<LineString> strings =
ImmutableList.builder();
public Builder() {
type(Type.MULTILINESTRING);
}
public Builder add(LineString line, LineString... lines) {
this.strings.add(line);
if (lines != null)
for (LineString l : lines)
add(l);
return this;
}
public Builder add(Supplier<LineString> line) {
return add(line.get());
}
public Builder add(Iterable<LineString> lines) {
this.strings.addAll(lines);
return this;
}
public MultiLineString doGet() {
return new MultiLineString(this);
}
@Override
protected Iterable<LineString> coordinates() {
return strings.build();
}
}
protected MultiLineString(
Builder builder) {
super(builder);
}
@Override
public Iterator<LineString> iterator() {
return coordinates().iterator();
}
@Override
protected MultiLineString makeWithBoundingBox() {
return new MultiLineString.Builder()
.from(this)
.add(this)
.boundingBox(
calculateBoundingBoxLineStrings(this)).get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<MultiLineString,Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(MultiLineString obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
protected boolean handle(Builder builder, String key, Object val) {
if ("coordinates".equals(key)) {
Iterable<LineString> list = (Iterable<LineString>) val;
builder.strings.addAll(list);
return true;
}
return false;
}
@Override
protected MultiLineString.Builder builder() {
return GeoMakers.multiLineString();
}
}
}

View File

@ -0,0 +1,107 @@
package com.ibm.common.geojson;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxPositions;
public final class MultiPoint
extends CoordinateGeometry<MultiPoint,Position,Iterable<Position>> {
public static final class Builder
extends CoordinateGeometry.Builder<Position,Iterable<Position>,MultiPoint,Builder> {
protected ImmutableList.Builder<Position> list =
ImmutableList.builder();
public Builder() {
type(GeoObject.Type.MULTIPOINT);
}
public Builder add(Position position, Position... positions) {
list.add(position);
if (positions != null)
list.add(positions);
return this;
}
public Builder add(Iterable<Position> positions) {
list.addAll(positions);
return this;
}
public Builder add(Supplier<Position> pos) {
return add(pos.get());
}
public Builder add(float x, float y) {
return add(GeoObject.position(x, y));
}
public Builder add(float x, float y, float z) {
return add(GeoObject.position(x,y,z));
}
@Override
protected Iterable<Position> coordinates() {
return list.build();
}
@Override
public MultiPoint doGet() {
return new MultiPoint(this);
}
}
protected MultiPoint(
Builder builder) {
super(builder);
}
@Override
public Iterator<Position> iterator() {
return coordinates().iterator();
}
@Override
protected MultiPoint makeWithBoundingBox() {
return new MultiPoint.Builder()
.from(this)
.add(this)
.boundingBox(calculateBoundingBoxPositions(this)).get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<MultiPoint,Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(MultiPoint obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
@Override
protected boolean handle(Builder builder, String key, Object val) {
if ("coordinates".equals(key)) {
Iterable<Position> list = (Iterable<Position>) val;
builder.list.addAll(list);
return true;
}
return false;
}
@Override
protected MultiPoint.Builder builder() {
return GeoMakers.multipoint();
}
}
}

View File

@ -0,0 +1,101 @@
package com.ibm.common.geojson;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxPolygons;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
public final class MultiPolygon
extends CoordinateGeometry<MultiPolygon, Polygon, Iterable<Polygon>>{
public static final class Builder
extends CoordinateGeometry.Builder<Polygon,Iterable<Polygon>, MultiPolygon, Builder> {
private final ImmutableList.Builder<Polygon> strings =
ImmutableList.builder();
public Builder() {
type(Type.MULTIPOLYGON);
}
public Builder add(Polygon poly, Polygon... polys) {
// TODO: Check hole requirement
this.strings.add(poly);
if (polys != null)
for (Polygon l : polys)
add(l);
return this;
}
public Builder add(Supplier<Polygon> poly) {
return add(poly.get());
}
public Builder add(Iterable<Polygon> polygons) {
this.strings.addAll(polygons);
return this;
}
public MultiPolygon doGet() {
return new MultiPolygon(this);
}
@Override
protected Iterable<Polygon> coordinates() {
return strings.build();
}
}
protected MultiPolygon(
Builder builder) {
super(builder);
}
@Override
public Iterator<Polygon> iterator() {
return coordinates().iterator();
}
@Override
protected MultiPolygon makeWithBoundingBox() {
return new MultiPolygon.Builder()
.from(this)
.add(this)
.boundingBox(calculateBoundingBoxPolygons(this))
.get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<MultiPolygon,Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(MultiPolygon obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
@Override
protected boolean handle(Builder builder, String key, Object val) {
if ("coordinates".equals(key)) {
Iterable<Polygon> list = (Iterable<Polygon>) val;
builder.strings.addAll(list);
return true;
}
return false;
}
@Override
protected MultiPolygon.Builder builder() {
return GeoMakers.multiPolygon();
}
}
}

View File

@ -0,0 +1,92 @@
package com.ibm.common.geojson;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
public final class Place extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Place, Builder> {
Builder() {
objectType("place");
}
public Builder address(Address address) {
return set("address", address);
}
public Builder address(Supplier<Address> address) {
return address(address.get());
}
@SuppressWarnings("deprecation")
public Builder position(AS1Position position) {
return set("position", position);
}
@SuppressWarnings("deprecation")
public Builder position(Supplier<AS1Position> position) {
return position(position.get());
}
@SuppressWarnings("deprecation")
public Builder position(
float latitude,
float longitude,
float altitude) {
return position(GeoMakers.as1Position(latitude, longitude, altitude));
}
public Builder geo(GeoObject<?> geo) {
return set("geo", geo);
}
public Builder geo(Supplier<? extends GeoObject<?>> geo) {
return geo(geo.get());
}
@Override
public Place get() {
return new Place(this);
}
}
private Place(Builder builder) {
super(builder);
}
public Address address() {
return this.<Address>get("address");
}
@SuppressWarnings("deprecation")
public AS1Position position() {
return this.<AS1Position>get("position");
}
public <G extends GeoObject<?>>G geo() {
return this.<G>get("geo");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Place> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Place obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Place.Builder builder() {
return GeoMakers.place();
}
}
}

View File

@ -0,0 +1,102 @@
package com.ibm.common.geojson;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import static com.google.common.collect.Iterables.getFirst;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBox;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
public final class Point
extends CoordinateGeometry<Point,Position,Position> {
public static final class Builder
extends CoordinateGeometry.Builder<Position,Position,Point,Builder> {
protected Position position;
public Builder() {
type(GeoObject.Type.POINT);
}
public Builder position(float x, float y, float z) {
this.position = GeoObject.position(x, y, z);
return this;
}
public Builder position(float x, float y) {
this.position = GeoObject.position(x,y);
return this;
}
public Builder position(Position position) {
this.position = position;
return this;
}
public Builder position(Supplier<Position> position) {
return position(position.get());
}
@Override
protected Position coordinates() {
return position;
}
@Override
public Point doGet() {
return new Point(this);
}
}
Point(Builder builder) {
super(builder);
}
@Override
public Iterator<Position> iterator() {
return coordinates().iterator();
}
@Override
protected Point makeWithBoundingBox() {
Position pos = getFirst(coordinates(),null);
return new Point.Builder()
.from(this)
.position(pos)
.boundingBox(calculateBoundingBox(pos))
.get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Point,Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(Point obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@Override
protected boolean handle(Builder builder, String key, Object val) {
if ("coordinates".equals(key)) {
builder.position = (Position) val;
return true;
}
return false;
}
@Override
protected Point.Builder builder() {
return GeoMakers.point();
}
}
}

View File

@ -0,0 +1,103 @@
package com.ibm.common.geojson;
import static com.google.common.base.Preconditions.checkArgument;
import static com.ibm.common.geojson.BoundingBox.calculateBoundingBoxLineStrings;
import java.io.ObjectStreamException;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
public final class Polygon
extends CoordinateGeometry<Polygon,LineString, Iterable<LineString>> {
public static final class Builder
extends CoordinateGeometry.Builder<LineString, Iterable<LineString>, Polygon, Builder> {
private final ImmutableList.Builder<LineString> strings =
ImmutableList.builder();
public Builder() {
type(Type.POLYGON);
}
public Builder add(LineString line, LineString... lines) {
checkArgument(line.linearRing(), "Polygon coordinates MUST be Linear Rings");
// TODO: Check hole requirement
this.strings.add(line);
if (lines != null)
for (LineString l : lines)
add(l);
return this;
}
public Builder add(Supplier<LineString> line) {
return add(line.get());
}
public Builder add(Iterable<LineString> lines) {
this.strings.addAll(lines);
return this;
}
public Polygon doGet() {
return new Polygon(this);
}
@Override
protected Iterable<LineString> coordinates() {
return strings.build();
}
}
protected Polygon(
Builder builder) {
super(builder);
}
@Override
public Iterator<LineString> iterator() {
return coordinates().iterator();
}
@Override
protected Polygon makeWithBoundingBox() {
return new Polygon.Builder()
.from(this)
.add(this)
.boundingBox(
calculateBoundingBoxLineStrings(this)).get();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Polygon,Builder> {
private static final long serialVersionUID = -2060301713159936281L;
protected SerializedForm(Polygon obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return doReadResolve();
}
@SuppressWarnings("unchecked")
@Override
protected boolean handle(Builder builder, String key, Object val) {
if ("coordinates".equals(key)) {
Iterable<LineString> list = (Iterable<LineString>) val;
builder.strings.addAll(list);
return true;
}
return false;
}
@Override
protected Polygon.Builder builder() {
return GeoMakers.polygon();
}
}
}

View File

@ -0,0 +1,130 @@
package com.ibm.common.geojson;
import static com.google.common.primitives.Floats.concat;
import static com.google.common.primitives.Floats.toArray;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Floats;
public final class Position
implements Iterable<Float>, Serializable {
public static final class Builder
implements Supplier<Position> {
private float x,y,z;
private boolean hasz = false;
private ImmutableList.Builder<Float> rest =
ImmutableList.builder();
public Builder northing(float x) {
this.x = x;
return this;
}
public Builder easting(float y) {
this.y = y;
return this;
}
public Builder altitude(float z) {
this.hasz = true;
this.z = z;
return this;
}
public Builder additional(float m) {
this.rest.add(m);
return this;
}
public Position get() {
return new Position(this);
}
}
private final float x,y,z;
private final boolean hasz;
private final float[] rest;
Position(Builder builder) {
this.x = builder.x;
this.y = builder.y;
this.z = builder.z;
this.hasz = builder.hasz;
this.rest = toArray(builder.rest.build());
}
public float northing() {
return x;
}
public float easting() {
return y;
}
public float altitude() {
return z;
}
public boolean hasAltitude() {
return hasz;
}
public int size() {
return values().length;
}
private float[] values() {
return hasz?
concat(new float[] {x,y,z}, rest) :
concat(new float[] {x,y}, rest);
}
public String toString() {
return Arrays.toString(values());
}
@Override
public Iterator<Float> iterator() {
return Floats.asList(values()).iterator();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm implements Serializable {
private static final long serialVersionUID = -2060301713159936285L;
private float x,y,z;
private boolean hasz;
private float[] rest;
protected SerializedForm(Position obj) {
this.x = obj.x;
this.y = obj.y;
this.z = obj.z;
this.hasz = obj.hasz;
this.rest = obj.rest;
}
Object readResolve() throws ObjectStreamException {
Position.Builder position =
new Position.Builder()
.northing(x)
.easting(y)
.altitude(z);
position.hasz = this.hasz;
if (rest != null)
for (float f : rest)
position.additional(f);
return position.get();
}
}
}

View File

@ -0,0 +1,331 @@
package com.ibm.common.geojson.as2;
import static com.google.common.base.Preconditions.checkArgument;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Map;
import com.google.common.base.Enums;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.internal.Adapter;
import com.ibm.common.geojson.BoundingBox;
import com.ibm.common.geojson.CRS;
import com.ibm.common.geojson.Feature;
import com.ibm.common.geojson.FeatureCollection;
import com.ibm.common.geojson.GeoMakers;
import com.ibm.common.geojson.GeoObject;
import com.ibm.common.geojson.Geometry;
import com.ibm.common.geojson.Geometry.CoordinateGeometry;
import com.ibm.common.geojson.GeometryCollection;
import com.ibm.common.geojson.LineString;
import com.ibm.common.geojson.MultiLineString;
import com.ibm.common.geojson.MultiPoint;
import com.ibm.common.geojson.MultiPolygon;
import com.ibm.common.geojson.Point;
import com.ibm.common.geojson.Polygon;
import com.ibm.common.geojson.Position;
@SuppressWarnings("rawtypes")
public class GeoAdapter
extends Adapter<GeoObject> {
@Override
public JsonElement serialize(
GeoObject geo,
Type type,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.add("type", context.serialize(geo.type(),GeoObject.Type.class));
switch(geo.type()) {
case POINT:
case MULTIPOINT:
case LINESTRING:
case MULTILINESTRING:
case MULTIPOLYGON:
case POLYGON:
CoordinateGeometry c =
(CoordinateGeometry) geo;
obj.add(
"coordinates",
context.serialize(
c.coordinates(),
Iterable.class));
break;
case GEOMETRYCOLLECTION:
GeometryCollection gc =
(GeometryCollection)geo;
obj.add(
"geometries",
context.serialize(
gc.geometries(),
Iterable.class));
break;
case FEATURE:
Feature feature =
(Feature) geo;
if (feature.id() != null)
obj.addProperty("id", feature.id());
Geometry<?,?> geometry = feature.geometry();
Map<String,Object> properties = feature.properties();
if (geometry != null)
obj.add(
"geometry",
context.serialize(feature.geometry()));
if (properties != null)
obj.add(
"properties",
context.serialize(properties));
break;
case FEATURECOLLECTION:
FeatureCollection fc =
(FeatureCollection)geo;
obj.add(
"features",
context.serialize(
fc.features(),
Iterable.class));
break;
default:
break;
}
if (geo.boundingBox() != null) {
BoundingBox bb = geo.boundingBox();
obj.add("bbox", context.serialize(bb, Iterable.class));
}
if (geo.crs() != null) {
CRS crs = geo.crs();
JsonObject crsobj = new JsonObject();
crsobj.addProperty("name", crs.type());
if (crs.size() > 0)
crsobj.add(
"properties",
context.serialize(crs.properties()));
obj.add("crs", crsobj);
}
return obj;
}
private Position toPosition(float[] pos) {
Position.Builder b =
new Position.Builder();
for (int n = 0; n < pos.length; n++) {
if (n == 0) b.northing(pos[n]);
else if (n == 1) b.easting(pos[n]);
else if (n == 2) b.altitude(pos[n]);
else b.additional(pos[n]);
}
return b.get();
}
@Override
public GeoObject deserialize(
JsonElement element,
Type type,
JsonDeserializationContext context)
throws JsonParseException {
GeoObject.Builder geo = null;
checkArgument(element.isJsonObject());
JsonObject obj = element.getAsJsonObject();
checkArgument(obj.has("type"));
GeoObject.Type et =
Enums.getIfPresent(
GeoObject.Type.class,
obj.get("type").getAsString().toUpperCase()).orNull();
checkArgument(et != null);
switch(et) {
case FEATURE:
geo = GeoMakers.feature();
break;
case FEATURECOLLECTION:
geo = GeoMakers.featureCollection();
type = Feature.class;
break;
case GEOMETRYCOLLECTION:
geo = GeoMakers.geometryCollection();
type = Geometry.class;
break;
case LINESTRING:
geo = GeoMakers.linestring();
type = Position.class;
break;
case MULTILINESTRING:
geo = GeoMakers.multiLineString();
type = LineString.class;
break;
case MULTIPOINT:
geo = GeoMakers.multipoint();
type = Position.class;
break;
case MULTIPOLYGON:
geo = GeoMakers.multiPolygon();
type = Polygon.class;
break;
case POINT:
geo = GeoMakers.point();
type = null;
break;
case POLYGON:
geo = GeoMakers.polygon();
type = LineString.class;
break;
}
for (Map.Entry<String,JsonElement> entry : obj.entrySet()) {
JsonElement el = entry.getValue();
String name = entry.getKey();
if ("crs".equals(name)) {
CRS.Builder cb = new CRS.Builder();
JsonObject o = el.getAsJsonObject();
if (o.has("type"))
cb.type(o.get("type").getAsString());
if (o.has("properties")) {
JsonObject p = o.get("properties").getAsJsonObject();
for (Map.Entry<String,JsonElement> e : p.entrySet()) {
cb.set(e.getKey(), context.deserialize(e.getValue(), Object.class));
}
}
geo.crs(cb.get());
} else if ("properties".equals(name)) {
geo.set(
"properties",
context.deserialize(
el,
Map.class));
} else if ("bbox".equals(name)) {
BoundingBox.Builder bb =
new BoundingBox.Builder();
float[] points = context.deserialize(el, float[].class);
bb.add(points);
geo.boundingBox(bb.get());
} else if ("features".equals(name)) {
Feature[] features = context.deserialize(el, Feature[].class);
FeatureCollection.Builder fcb = (FeatureCollection.Builder)geo;
for (Feature f : features)
fcb.add(f);
} else if ("coordinates".equals(name)) {
switch(et) {
case LINESTRING: {
LineString.Builder lsb = (LineString.Builder) geo;
float[][] positions = context.deserialize(el, float[][].class);
boolean ring = ring(positions);
if (ring)
lsb.linearRing();
for (int n = 0; n < positions.length; n++) {
if (!ring || (ring && n < positions.length - 1))
lsb.add(toPosition(positions[n]));
}
break;
}
case MULTIPOINT: {
MultiPoint.Builder lsb = (MultiPoint.Builder) geo;
float[][] positions = context.deserialize(el, float[][].class);
for (float[] pos : positions)
lsb.add(toPosition(pos));
break;
}
case MULTILINESTRING: {
MultiLineString.Builder mlb = (MultiLineString.Builder) geo;
float[][][] positions = context.deserialize(el, float[][][].class);
for (float[][] lines : positions) {
LineString.Builder lsb =
GeoMakers.linestring();
boolean ring = ring(lines);
if (ring)
lsb.linearRing();
for (int n = 0; n < lines.length; n++) {
if (!ring || (ring && n < lines.length - 1))
lsb.add(toPosition(lines[n]));
}
for (float[] pos : lines)
lsb.add(toPosition(pos));
mlb.add(lsb);
}
break;
}
case POLYGON: {
Polygon.Builder mlb = (Polygon.Builder) geo;
float[][][] positions = context.deserialize(el, float[][][].class);
for (float[][] lines : positions) {
LineString.Builder lsb =
GeoMakers.linestring();
for (float[] pos : lines)
lsb.add(toPosition(pos));
mlb.add(lsb);
}
break;
}
case MULTIPOLYGON: {
MultiPolygon.Builder mpb = (MultiPolygon.Builder) geo;
float[][][][] positions = context.deserialize(el, float[][][][].class);
for (float[][][] polygons : positions) {
Polygon.Builder pb = GeoMakers.polygon();
for (float[][] lines : polygons) {
LineString.Builder lsb =
GeoMakers.linestring();
for (float[] pos : lines)
lsb.add(toPosition(pos));
pb.add(lsb);
}
mpb.add(pb);
}
break;
}
case POINT:
Point.Builder pb = (Point.Builder)geo;
float[] position = context.deserialize(el, float[].class);
pb.position(toPosition(position));
break;
default:
break;
}
} else if ("geometries".equals(name)) {
Geometry[] geos = context.deserialize(el, Geometry[].class);
GeometryCollection.Builder fcb = (GeometryCollection.Builder)geo;
for (Geometry<?,?> g : geos)
fcb.add(g);
} else {
if (el.isJsonArray()) {
geo.set(name, context.deserialize(el, Object.class));
} else if (el.isJsonObject()) {
geo.set(name, context.deserialize(el, GeoObject.class));
} else if (el.isJsonPrimitive()) {
JsonPrimitive p = el.getAsJsonPrimitive();
if (p.isBoolean())
geo.set(name, p.getAsBoolean());
else if (p.isNumber())
geo.set(name, p.getAsNumber());
else if (p.isString())
geo.set(name, p.getAsString());
}
}
}
return geo.get();
}
private static boolean ring(float[][] line) {
return ring(first(line),last(line));
}
private static boolean ring(float[] p1, float[] p2) {
return Arrays.equals(p1,p2);
}
private static float[] first(float[][] line) {
if (line.length == 0) return null;
return line[0];
}
private static float[] last(float[][] line) {
if (line.length == 0) return null;
return line[line.length - 1];
}
}

View File

@ -0,0 +1,75 @@
package com.ibm.common.geojson.as2;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.internal.EnumAdapter;
import com.ibm.common.activitystreams.internal.Model;
import com.ibm.common.activitystreams.internal.Schema;
import com.ibm.common.activitystreams.internal.Schema.Builder;
import com.ibm.common.activitystreams.util.Module;
import com.ibm.common.geojson.AS1Position;
import com.ibm.common.geojson.Address;
import com.ibm.common.geojson.GeoObject;
import com.ibm.common.geojson.Place;
@SuppressWarnings("deprecation")
public final class GeoModule
implements Module {
public static final Module instance =
new GeoModule();
public static final Model place =
Schema.object.template()
.type(Place.class, Place.Builder.class)
.as("geo", GeoObject.class)
.as("address", Address.class)
.as("position", AS1Position.class)
.get();
public static final Model address =
Schema.object.template()
.type(Address.class, Address.Builder.class)
.string(
"country",
"formatted",
"locality",
"postalCode",
"region",
"streetAddress")
.get();
public static final Model as1Position =
Schema.object.template()
.type(AS1Position.class, AS1Position.Builder.class)
.floatValue(
"latitude",
"longitude",
"altitude")
.get();
@Override
public void apply(
Builder builder) {
builder.map("place", place)
.map("address", address)
.map("position", as1Position);
}
@Override
public void apply(
IO.Builder builder,
Schema schema) {
final GeoObjectAdapter base =
new GeoObjectAdapter(schema);
final GeoAdapter geo =
new GeoAdapter();
builder.hierarchicalAdapter(Place.class, base)
.hierarchicalAdapter(Address.class, base)
.hierarchicalAdapter(AS1Position.class, base)
.hierarchicalAdapter(GeoObject.class, geo)
.hierarchicalAdapter(
GeoObject.Type.class,
new EnumAdapter<GeoObject.Type>(GeoObject.Type.class));
}
}

View File

@ -0,0 +1,64 @@
package com.ibm.common.geojson.as2;
import java.lang.reflect.Type;
import com.google.common.collect.ImmutableSet;
import com.ibm.common.activitystreams.ASObject.AbstractBuilder;
import com.ibm.common.activitystreams.internal.ASObjectAdapter;
import com.ibm.common.activitystreams.internal.Model;
import com.ibm.common.activitystreams.internal.Schema;
import com.ibm.common.geojson.AS1Position;
import com.ibm.common.geojson.Address;
import com.ibm.common.geojson.GeoMakers;
import com.ibm.common.geojson.Place;
@SuppressWarnings("deprecation")
public class GeoObjectAdapter
extends ASObjectAdapter {
protected GeoObjectAdapter(Schema schema) {
super(schema);
}
private static final ImmutableSet<? extends Type> knownTypes =
ImmutableSet.of(Address.class,AS1Position.class,Place.class);
@Override
protected boolean knowsType(Type type) {
if (super.knowsType(type))
return true;
return knownTypes.contains(type);
}
@Override
protected AbstractBuilder<?, ?> builderFor(Type type) {
if (super.knowsType(type))
return super.builderFor(type);
if (type == Address.class) {
return GeoMakers.address();
} else if (type == AS1Position.class) {
return GeoMakers.as1Position();
} else if (type == Place.class) {
return GeoMakers.place();
} else return null;
}
@Override
protected Model modelFor(Type type) {
if (super.knowsType(type))
return super.modelFor(type);
if (type == Address.class) {
return schema().forObjectClassOrType(
Address.Builder.class,
"address");
} else if (type == AS1Position.class) {
return schema().forObjectClassOrType(
AS1Position.Builder.class,
"position");
} else if (type == Place.class) {
return schema().forObjectClassOrType(
Place.Builder.class,
"place");
} else return null;
}
}

143
legacy/pom.xml Normal file
View File

@ -0,0 +1,143 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>activitystreams-legacy</artifactId>
<name>Activity Streams 2.0 - Legacy objectTypes</name>
<description>
Implementation of Legacy Activity Streams 1.0 objectTypes for
use with the Activity Streams 2.0 Reference Implementation
</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<charset>UTF-8</charset>
<additionalparam>-XDignore.symbol.file</additionalparam>
<show>public</show>
<links>
<link>http://www.joda.org/joda-time/apidocs</link>
<link>http://docs.guava-libraries.googlecode.com/git-history/v16.0.1/javadoc/</link>
</links>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Export-Package>com.ibm.common.activitystreams.legacy.*</Export-Package>
<Import-Package>
com.ibm.common.activitystreams.*,
com.google.gson.*,
com.google.common.*,
org.joda.time.*
</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<versionRange>[2.3.7,)</versionRange>
<goals>
<goal>manifest</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.ibm.common</groupId>
<artifactId>activitystreams-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,61 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
public final class AudioVisual
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<AudioVisual,Builder> {
public Builder embedCode(String embed) {
return set("embedCode", embed);
}
public Builder stream(MediaLink mediaLink) {
return set("stream", mediaLink);
}
public Builder stream(Supplier<? extends MediaLink> mediaLink) {
return stream(mediaLink.get());
}
public AudioVisual get() {
return new AudioVisual(this);
}
}
private AudioVisual(Builder builder) {
super(builder);
}
public String embedCode() {
return getString("embedCode");
}
public MediaLink stream() {
return this.<MediaLink>get("stream");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<AudioVisual> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(AudioVisual obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected AudioVisual.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,161 @@
package com.ibm.common.activitystreams.legacy;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import com.google.common.hash.Hashing;
import com.google.common.hash.HashingInputStream;
import com.google.common.hash.HashingOutputStream;
import com.google.common.io.BaseEncoding;
import com.google.common.net.MediaType;
import com.ibm.common.activitystreams.ASObject;
public final class Binary
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Binary, Builder> {
Builder() {
objectType("binary");
}
public Builder data(
InputStream in)
throws IOException {
return data(in,null);
}
public Builder gzipData(InputStream in) throws IOException {
return data(in, Compression.GZipCompression);
}
public Builder deflateData(InputStream in) throws IOException {
return data(in, Compression.DeflateCompression);
}
public Builder data(
InputStream in,
Compression<?,?> compression)
throws IOException {
StringWriter writer = new StringWriter();
OutputStream out =
BaseEncoding.base64Url().encodingStream(writer);
if (compression != null)
out = compression.compressor(out);
HashingOutputStream hout =
new HashingOutputStream(
Hashing.md5(), out);
byte[] buf = new byte[1024];
int r = -1;
long size = 0;
while((r = in.read(buf)) > -1) {
hout.write(buf,0,r);
size += r;
}
set("length", size);
if (compression != null) {
set("compression", compression.label());
compression.finish(out);
}
hout.close();
set("md5", hout.hash().toString());
return set("data",writer.toString());
}
public Builder md5(String md5) {
return set("md5", md5);
}
public Builder fileUrl(String fileUrl) {
return set("fileUrl", fileUrl);
}
@Override
public Builder mediaType(MediaType mt) {
return set("mimeType", mt);
}
public Binary get() {
return new Binary(this);
}
}
private Binary(Builder builder) {
super(builder);
}
public String fileUrl() {
return getString("fileUrl");
}
public long length() {
return getLong("length");
}
public String compression() {
return getString("compression");
}
public boolean isGzip() {
return "gzip".equalsIgnoreCase(compression());
}
public boolean isDeflate() {
return "deflate".equalsIgnoreCase(compression());
}
public String md5() {
return getString("md5");
}
public String data() {
return getString("data");
}
public InputStream read() throws IOException {
Compression<?,?> compression =
isGzip() ? Compression.GZipCompression :
isDeflate() ? Compression.DeflateCompression :
null;
return read(compression);
}
public InputStream read(Compression<?,?> compression) throws IOException {
StringReader reader = new StringReader(data());
InputStream in = BaseEncoding.base64Url().decodingStream(reader);
if (compression != null)
in = compression.decompressor(in);
if (has("md5"))
in = new HashingInputStream(Hashing.md5(),in);
return in;
}
@Override
public MediaType mediaType() {
return this.<MediaType>get("mimeType");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Binary> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Binary obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Binary.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,52 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.ibm.common.activitystreams.ASObject;
public class Bookmark
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Bookmark, Builder> {
Builder() {
objectType("bookmark");
}
public Builder targetUrl(String url) {
return set("targetUrl", url);
}
public Bookmark get() {
return new Bookmark(this);
}
}
private Bookmark(Builder builder) {
super(builder);
}
public String targetUrl() {
return getString("targetUrl");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Bookmark> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Bookmark obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Bookmark.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,53 @@
package com.ibm.common.activitystreams.legacy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.DeflaterInputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public interface Compression<O extends OutputStream, I extends InputStream> {
String label();
O compressor(OutputStream wrap) throws IOException;
I decompressor(InputStream in) throws IOException;
void finish(OutputStream out) throws IOException;
public static final Compression<GZIPOutputStream,GZIPInputStream> GZipCompression =
new Compression<GZIPOutputStream,GZIPInputStream>() {
public String label() {
return "gzip";
}
public GZIPOutputStream compressor(OutputStream wrap) throws IOException {
return new GZIPOutputStream(wrap);
}
public GZIPInputStream decompressor(InputStream in) throws IOException {
return new GZIPInputStream(in);
}
public void finish(OutputStream out) throws IOException {
if (out instanceof GZIPOutputStream)
((GZIPOutputStream)out).finish();
}
};
public static final Compression<DeflaterOutputStream, DeflaterInputStream> DeflateCompression =
new Compression<DeflaterOutputStream, DeflaterInputStream>() {
public String label() {
return "deflate";
}
public DeflaterOutputStream compressor(OutputStream wrap)
throws IOException {
return new DeflaterOutputStream(wrap);
}
public DeflaterInputStream decompressor(InputStream in)
throws IOException {
return new DeflaterInputStream(in);
}
public void finish(OutputStream out) throws IOException {
if (out instanceof DeflaterOutputStream)
((DeflaterOutputStream)out).finish();
}
};
}

View File

@ -0,0 +1,118 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.Collection;
public class Event
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Event, Builder> {
Builder() {
objectType("event");
}
public Builder attendedBy(Collection collection) {
return set("attendedBy", collection);
}
public Builder attendedBy(Supplier<? extends Collection> collection) {
return attendedBy(collection.get());
}
public Builder attending(Collection collection) {
return set("attending", collection);
}
public Builder attending(Supplier<? extends Collection> collection) {
return attending(collection.get());
}
public Builder invited(Collection collection) {
return set("invited", collection);
}
public Builder invited(Supplier<? extends Collection> collection) {
return invited(collection.get());
}
public Builder maybeAttending(Collection collection) {
return set("maybeAttending", collection);
}
public Builder maybeAttending(Supplier<? extends Collection> collection) {
return maybeAttending(collection.get());
}
public Builder notAttendedBy(Collection collection) {
return set("notAttendedBy", collection);
}
public Builder notAttendedBy(Supplier<? extends Collection> collection) {
return notAttendedBy(collection.get());
}
public Builder notAttending(Collection collection) {
return set("notAttending", collection);
}
public Builder notAttending(Supplier<? extends Collection> collection) {
return notAttending(collection.get());
}
public Event get() {
return new Event(this);
}
}
private Event(Builder builder) {
super(builder);
}
public Collection attendedBy() {
return this.<Collection>get("attendedBy");
}
public Collection attending() {
return this.<Collection>get("attending");
}
public Collection invited() {
return this.<Collection>get("invited");
}
public Collection maybeAttending() {
return this.<Collection>get("maybeAttending");
}
public Collection notAttendedBy() {
return this.<Collection>get("notAttendedBy");
}
public Collection notAttending() {
return this.<Collection>get("notAttending");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Event> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Event obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Event.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,63 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.net.MediaType;
import com.ibm.common.activitystreams.ASObject;
public class File
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<File, Builder> {
Builder() {
objectType("file");
}
public Builder fileUrl(String url) {
return set("fileUrl", url);
}
@Override
public Builder mediaType(MediaType mt) {
return set("mimeType", mt);
}
public File get() {
return new File(this);
}
}
private File(Builder builder) {
super(builder);
}
@Override
public MediaType mediaType() {
return this.<MediaType>get("mimeType");
}
public String fileUrl() {
return getString("fileUrl");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<File> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(File obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected File.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,63 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.collect.ImmutableList;
import com.ibm.common.activitystreams.ASObject;
public class Issue
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Issue, Builder> {
Builder() {
objectType("issue");
}
public Builder types(String type, String... types) {
ImmutableList.Builder<String> list =
ImmutableList.builder();
if (type != null)
list.add(type);
if (types != null)
list.add(types);
return types(list.build());
}
public Builder types(Iterable<String> types) {
return set("types", types);
}
public Issue get() {
return new Issue(this);
}
}
private Issue(Builder builder) {
super(builder);
}
public Iterable<String> types() {
return this.<Iterable<String>>get("types");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Issue> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Issue obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Issue.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,158 @@
package com.ibm.common.activitystreams.legacy;
import com.ibm.common.activitystreams.ASObject;
import static com.ibm.common.activitystreams.Makers.object;
public final class LegacyMakers {
private LegacyMakers() {}
public static Binary.Builder binary() {
return new Binary.Builder();
}
public static Task.Builder task() {
return new Task.Builder();
}
public static WithImage.Builder withImage() {
return new WithImage.Builder();
}
public static Question.Builder question() {
return new Question.Builder();
}
public static WithImage.Builder product() {
return new WithImage.Builder().objectType("product");
}
public static WithImage.Builder image() {
return new WithImage.Builder().objectType("image");
}
public static File.Builder file() {
return new File.Builder();
}
public static Bookmark.Builder bookmark() {
return new Bookmark.Builder();
}
public static Bookmark bookmark(String targetUrl) {
return bookmark().targetUrl(targetUrl).get();
}
public static Membership.Builder role() {
return new Membership.Builder().objectType("role");
}
public static Membership.Builder group() {
return new Membership.Builder().objectType("group");
}
public static Issue.Builder issue() {
return new Issue.Builder();
}
public static Membership.Builder membership() {
return new Membership.Builder();
}
public static Event.Builder event() {
return new Event.Builder();
}
public static MediaLink.Builder mediaLink() {
return new MediaLink.Builder();
}
public static MediaLink mediaLink(String url) {
return mediaLink().url(url).get();
}
public static ASObject.Builder permission() {
return object("permission");
}
public static AudioVisual.Builder video() {
return new AudioVisual.Builder().objectType("video");
}
public static AudioVisual.Builder audioVisual() {
return new AudioVisual.Builder();
}
public static AudioVisual.Builder audio() {
return new AudioVisual.Builder().objectType("audio");
}
public static ASObject.Builder alert() {
return object("alert");
}
public static ASObject.Builder application() {
return object("application");
}
public static ASObject.Builder article() {
return object("article");
}
public static ASObject.Builder badge() {
return object("badge");
}
public static ASObject.Builder comment() {
return object("comment");
}
public static ASObject.Builder device() {
return object("device");
}
public static ASObject.Builder game() {
return object("game");
}
public static ASObject.Builder job() {
return object("job");
}
public static ASObject.Builder note() {
return object("note");
}
public static ASObject.Builder offer() {
return object("offer");
}
public static ASObject.Builder organization() {
return object("organization");
}
public static ASObject.Builder page() {
return object("page");
}
public static ASObject.Builder person() {
return object("person");
}
public static ASObject.Builder process() {
return object("process");
}
public static ASObject.Builder review() {
return object("review");
}
public static ASObject.Builder service() {
return object("service");
}
public static Membership.Builder team() {
return new Membership.Builder().objectType("team");
}
}

View File

@ -0,0 +1,136 @@
package com.ibm.common.activitystreams.legacy;
import java.lang.reflect.Type;
import com.google.common.net.MediaType;
import com.ibm.common.activitystreams.Collection;
import com.ibm.common.activitystreams.IO;
import com.ibm.common.activitystreams.internal.Model;
import com.ibm.common.activitystreams.internal.Schema;
import com.ibm.common.activitystreams.internal.Schema.Builder;
import com.ibm.common.activitystreams.util.Module;
public class LegacyModule
implements Module {
public static final Module instance = new LegacyModule();
public static final Model binary =
Schema.object.template()
.type(Binary.class, Binary.Builder.class)
.string("compression", "md5", "data", "fileUrl")
.as("mimeType", MediaType.class)
.integer("length")
.get();
public static final Model audioVisual =
Schema.object.template()
.type(AudioVisual.class, AudioVisual.Builder.class)
.string("embedCode")
.as("stream", MediaLink.class)
.get();
public static final Model withImage =
Schema.object.template()
.type(WithImage.class, WithImage.Builder.class)
.as("fullImage", MediaLink.class)
.get();
public static final Model bookmark =
Schema.object.template()
.type(Bookmark.class, Bookmark.Builder.class)
.string("targetUrl")
.get();
public static final Model event =
Schema.object.template()
.type(Event.class, Event.Builder.class)
.as("attendedBy", Collection.class)
.as("attending", Collection.class)
.as("invited", Collection.class)
.as("maybeAttending", Collection.class)
.as("notAttendedBy", Collection.class)
.as("notAttending", Collection.class)
.get();
public static final Model membership =
Schema.object.template()
.type(Membership.class, Membership.Builder.class)
.as("members", Collection.class)
.get();
public static final Model file =
Schema.object.template()
.type(File.class, File.Builder.class)
.string("fileUrl")
.as("mimeType", MediaType.class)
.get();
public static final Model issue =
Schema.object.template()
.type(Issue.class, Issue.Builder.class)
.string("types")
.get();
public static final Model question =
Schema.object.template()
.type(Question.class, Question.Builder.class)
.linkValue("options")
.get();
public static final Model task =
Schema.object.template()
.type(Task.class, Task.Builder.class)
.object("actor", "object")
.dateTime("by")
.as("required", Boolean.class)
.string("verb")
.as("prerequisites", Task.class)
.as("supersedes", Task.class)
.get();
public void apply(Builder builder) {
builder.map("alert", Schema.object)
.map("binary", binary)
.map("application", Schema.object)
.map("article", Schema.object)
.map("audio", audioVisual)
.map("badge", Schema.object)
.map("bookmark",bookmark)
.map("comment", Schema.object)
.map("device", Schema.object)
.map("event", event)
.map("file", file)
.map("game", Schema.object)
.map("group", membership)
.map("image", withImage)
.map("issue", issue)
.map("job", Schema.object)
.map("note", Schema.object)
.map("offer", Schema.object)
.map("organization", Schema.object)
.map("page", Schema.object)
.map("person", Schema.object)
.map("process", Schema.object)
.map("product", Schema.object)
.map("question", question)
.map("review", Schema.object)
.map("role", membership)
.map("service", Schema.object)
.map("team", membership)
.map("video", audioVisual)
;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void apply(
IO.Builder builder,
Schema schema) {
LegacyObjectAdapter base =
new LegacyObjectAdapter(schema);
builder.adapter(MediaLink.class, new MediaLinkAdapter());
for (Type type : LegacyObjectAdapter.knownTypes)
builder.hierarchicalAdapter((Class)type, base);
}
}

View File

@ -0,0 +1,98 @@
package com.ibm.common.activitystreams.legacy;
import java.lang.reflect.Type;
import com.google.common.collect.ImmutableSet;
import com.ibm.common.activitystreams.ASObject.AbstractBuilder;
import com.ibm.common.activitystreams.internal.ASObjectAdapter;
import com.ibm.common.activitystreams.internal.Model;
import com.ibm.common.activitystreams.internal.Schema;
import static com.ibm.common.activitystreams.Makers.object;
public class LegacyObjectAdapter
extends ASObjectAdapter {
protected LegacyObjectAdapter(Schema schema) {
super(schema);
}
@SuppressWarnings("unchecked")
public static final ImmutableSet<? extends Type> knownTypes =
ImmutableSet.of(
Binary.class,
AudioVisual.class,
Bookmark.class,
Event.class,
File.class,
Issue.class,
Membership.class,
Question.class,
Task.class,
WithImage.class);
@Override
protected boolean knowsType(Type type) {
if (super.knowsType(type))
return true;
return knownTypes.contains(type);
}
@Override
protected AbstractBuilder<?, ?> builderFor(Type type) {
if (super.knowsType(type))
return super.builderFor(type);
if (knowsType(type)) {
if (type == AudioVisual.class)
return LegacyMakers.audioVisual();
else if (type == Binary.class)
return LegacyMakers.binary();
else if (type == Bookmark.class)
return LegacyMakers.bookmark();
else if (type == Event.class)
return LegacyMakers.event();
else if (type == File.class)
return LegacyMakers.file();
else if (type == Issue.class)
return LegacyMakers.issue();
else if (type == Membership.class)
return LegacyMakers.membership();
else if (type == Question.class)
return LegacyMakers.question();
else if (type == Task.class)
return LegacyMakers.task();
else if (type == WithImage.class)
return LegacyMakers.withImage();
else return object();
} else return null;
}
@Override
protected Model modelFor(Type type) {
if (super.knowsType(type))
return super.modelFor(type);
if (knowsType(type)) {
if (type == AudioVisual.class)
return LegacyModule.audioVisual;
else if (type == Bookmark.class)
return LegacyModule.bookmark;
else if (type == Binary.class)
return LegacyModule.binary;
else if (type == Event.class)
return LegacyModule.event;
else if (type == File.class)
return LegacyModule.file;
else if (type == Issue.class)
return LegacyModule.issue;
else if (type == Membership.class)
return LegacyModule.membership;
else if (type == Question.class)
return LegacyModule.question;
else if (type == Task.class)
return LegacyModule.task;
else if (type == WithImage.class)
return LegacyModule.withImage;
else return Schema.object;
} else return null;
}
}

View File

@ -0,0 +1,107 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.ibm.common.activitystreams.util.AbstractWritable;
public final class MediaLink
extends AbstractWritable
implements Iterable<String>, Serializable {
public static final class Builder
extends AbstractWritableBuilder<MediaLink,Builder>
implements Supplier<MediaLink> {
private Map<String,Object> map =
Maps.newHashMap();
public Builder duration(int duration) {
map.put("duration", duration);
return this;
}
public Builder height(int height) {
map.put("height", height);
return this;
}
public Builder width(int width) {
map.put("width", width);
return this;
}
public Builder url(String url) {
map.put("url", url);
return this;
}
public Builder set(String key, Object val) {
map.put(key,val);
return this;
}
public MediaLink get() {
return new MediaLink(this);
}
}
private final ImmutableMap<String,Object> map;
private MediaLink(Builder builder) {
super(builder);
this.map = ImmutableMap.copyOf(builder.map);
}
public String url() {
return (String)map.get("url");
}
public int duration() {
return (Integer)map.get("duration");
}
public int height() {
return (Integer)map.get("height");
}
public int width() {
return (Integer)map.get("width");
}
@SuppressWarnings("unchecked")
public <T>T get(String key) {
return (T)map.get(key);
}
public Iterator<String> iterator() {
return map.keySet().iterator();
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
implements Serializable {
private static final long serialVersionUID = -2060301713159936285L;
private ImmutableMap<String,Object> map;
protected SerializedForm(MediaLink obj) {
this.map = obj.map;
}
Object readResolve() throws ObjectStreamException {
MediaLink.Builder builder =
new Builder();
builder.map.putAll(map);
return builder.get();
}
}
}

View File

@ -0,0 +1,64 @@
package com.ibm.common.activitystreams.legacy;
import java.lang.reflect.Type;
import java.util.Map;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.ibm.common.activitystreams.ASObject;
import static com.ibm.common.activitystreams.internal.ASObjectAdapter.primConverter;
import com.ibm.common.activitystreams.internal.Adapter;
public final class MediaLinkAdapter
extends Adapter<MediaLink> {
public JsonElement serialize(
MediaLink src,
Type typeOfSrc,
JsonSerializationContext context) {
JsonObject el = new JsonObject();
for (String key : src) {
Object val = src.get(key);
if (val != null)
el.add(key, context.serialize(val, val.getClass()));
}
return el;
}
public MediaLink deserialize(
JsonElement json,
Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
checkArgument(json.isJsonObject());
JsonObject obj = (JsonObject) json;
MediaLink.Builder builder =
LegacyMakers.mediaLink();
for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
String name = entry.getKey();
JsonElement val = entry.getValue();
if (val.isJsonPrimitive())
builder.set(
name,
primConverter.convert(val.getAsJsonPrimitive()));
else if (val.isJsonArray())
builder.set(
name,
context.deserialize(val, Iterable.class));
else if (val.isJsonObject())
builder.set(
name,
context.deserialize(
val,
ASObject.class));
}
return builder.get();
}
}

View File

@ -0,0 +1,53 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.Collection;
public class Membership extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Membership, Builder> {
public Builder members(Collection collection) {
return set("members", collection);
}
public Builder members(Supplier<? extends Collection> collection) {
return members(collection.get());
}
public Membership get() {
return new Membership(this);
}
}
private Membership(Builder builder) {
super(builder);
}
public Collection members() {
return this.<Collection>get("members");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Membership> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Membership obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Membership.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,76 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.LinkValue;
public class Question extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Question, Builder> {
Builder() {
objectType("question");
}
public Builder option(String url, String... urls) {
if (url != null)
link("options", url);
if (urls != null)
for (String u : urls)
link("options", u);
return this;
}
public Builder option(LinkValue link, LinkValue... links) {
if (link != null)
link("options", link);
if (links != null)
for (LinkValue l : links)
link("options", l);
return this;
}
public Builder option(Supplier<? extends LinkValue> link) {
return option(link.get());
}
public Question get() {
return new Question(this);
}
}
public Question(Builder builder) {
super(builder);
}
public Iterable<LinkValue> options() {
return links("options");
}
public Iterable<LinkValue> options(Predicate<? super LinkValue> filter) {
return links("options", filter);
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Question> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Question obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Question.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,175 @@
package com.ibm.common.activitystreams.legacy;
import static com.google.common.collect.Iterables.transform;
import java.io.ObjectStreamException;
import org.joda.time.DateTime;
import org.joda.time.ReadableDuration;
import org.joda.time.ReadablePeriod;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
import com.ibm.common.activitystreams.LinkValue;
public class Task
extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<Task, Builder> {
Builder() {
objectType("task");
}
public Builder actor(ASObject actor) {
return set("actor", actor);
}
public Builder actor(Supplier<? extends ASObject> actor) {
return actor(actor.get());
}
public Builder object(ASObject object) {
return set("object", object);
}
public Builder object(Supplier<? extends ASObject> object) {
return object(object.get());
}
public Builder prerequisites(Task task, Task... tasks) {
if (task != null)
link("prerequisites",task);
if (tasks != null)
for (Task t : tasks)
link("prerequisites", t);
return this;
}
public Builder prerequisites(Supplier<? extends Task> task) {
return prerequisites(task.get());
}
public Builder supersedes(Task task, Task... tasks) {
if (task != null)
link("supersedes",task);
if (tasks != null)
for (Task t : tasks)
link("supersedes", t);
return this;
}
public Builder supersedes(Supplier<? extends Task> task) {
return supersedes(task.get());
}
public Builder required(boolean on) {
return set("required", on);
}
public Builder required() {
return required(true);
}
public Builder verb(String verb) {
return set("verb", verb);
}
public Builder by(DateTime dt) {
return this._dt("by", dt);
}
public Builder byNow() {
return this._dtNow("by");
}
public Builder byFromNow(ReadableDuration duration) {
return this._dtFromNow("by", duration);
}
public Builder byFromNow(ReadablePeriod period) {
return this._dtFromNow("by", period);
}
public Builder by(DateTime dt, ReadableDuration duration) {
return this._dtFrom("by", dt, duration);
}
public Builder by(DateTime dt, ReadablePeriod period) {
return this._dtFrom("by", dt, period);
}
public Task get() {
return new Task(this);
}
}
private Task(Builder builder) {
super(builder);
}
public <A extends ASObject>A actor() {
return this.<A>get("actor");
}
public <A extends ASObject>A object() {
return this.<A>get("object");
}
public DateTime by() {
return getDateTime("by");
}
public String verb() {
return getString("verb");
}
public boolean required() {
return getBoolean("required");
}
public Iterable<Task> supersedes() {
return transform(links("supersedes",filter), transformer);
}
public Iterable<Task> prerequisites() {
return transform(links("prerequisites",filter), transformer);
}
private static final Predicate<LinkValue> filter =
new Predicate<LinkValue>() {
public boolean apply(LinkValue input) {
return input instanceof Task;
}
};
private static final Function<LinkValue,Task> transformer =
new Function<LinkValue,Task>() {
public Task apply(LinkValue input) {
return (Task)input;
}
};
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<Task> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(Task obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected Task.Builder builder() {
return new Builder();
}
}
}

View File

@ -0,0 +1,52 @@
package com.ibm.common.activitystreams.legacy;
import java.io.ObjectStreamException;
import com.google.common.base.Supplier;
import com.ibm.common.activitystreams.ASObject;
public class WithImage extends ASObject {
public static final class Builder
extends ASObject.AbstractBuilder<WithImage, Builder> {
public Builder fullImage(MediaLink link) {
return set("fullImage", link);
}
public Builder fullImage(Supplier<? extends MediaLink> link) {
return fullImage(link.get());
}
public WithImage get() {
return new WithImage(this);
}
}
private WithImage(Builder builder) {
super(builder);
}
public MediaLink fullImage() {
return this.<MediaLink>get("fullImage");
}
Object writeReplace() throws java.io.ObjectStreamException {
return new SerializedForm(this);
}
private static class SerializedForm
extends AbstractSerializedForm<WithImage> {
private static final long serialVersionUID = -2060301713159936285L;
protected SerializedForm(WithImage obj) {
super(obj);
}
Object readResolve() throws ObjectStreamException {
return super.doReadResolve();
}
protected WithImage.Builder builder() {
return new Builder();
}
}
}

Some files were not shown because too many files have changed in this diff Show More