/**
* Copyright 2013 OpenSocial Foundation
* Copyright 2013 International Business Machines Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Utility library for working with Activity Streams Actions
* Requires underscorejs.
*
* @author James M Snell (jasnell@us.ibm.com)
*/
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<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<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<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<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<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<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<LinkValue>
**/
public Iterable<LinkValue> result() {
return links("result");
}
/**
* Returns the matching result(s)
* @param filter
* @return java.util.Iterable<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<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<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();
}
}
}