You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2010/09/07 10:02:18 UTC
svn commit: r993268 [2/8] - in /shindig/branches/2.0.x: ./ config/
content/container/ content/samplecontainer/ content/sampledata/
extras/src/main/java/org/apache/shindig/extras/
extras/src/main/java/org/apache/shindig/extras/as/ extras/src/main/java/o...
Modified: shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityObject.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityObject.java?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityObject.java (original)
+++ shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityObject.java Tue Sep 7 08:02:11 2010
@@ -25,106 +25,245 @@ import org.apache.shindig.extras.as.core
import com.google.inject.ImplementedBy;
+/**
+ * A representation of an ActivityStream object, a thing which participates in an Activity.
+ */
@ImplementedBy(ActivityObjectImpl.class)
@Exportablebean
public interface ActivityObject {
-
- /*
- * Fields that represent JSON elements for an activity entry.
- */
- public static enum Field {
- ID("id"),
- NAME("name"),
- SUMMARY("summary"),
- MEDIA("media"),
- PERMALINK("permalink"),
- TYPE("type"),
- IN_REPLY_TO("inReplyTo"),
- ATTACHED("attached"),
- REPLY("reply"),
- REACTION("reaction"),
- ACTION("action"),
- UPSTREAM_DUPLICATE_ID("upstreamDuplicateId"),
- DOWNSTREAM_DUPLICATE_ID("downstreamDuplicateId"),
- STANDARD_LINK("standardLink");
-
- /*
- * The name of the JSON element.
- */
- private final String jsonString;
-
- /*
- * Constructs the field base for the JSON element.
- *
- * @param jsonString the name of the element
- */
- private Field(String jsonString) {
- this.jsonString = jsonString;
- }
-
- /*
- * Returns the name of the JSON element.
- *
- * @return String the name of the JSON element
- */
- public String toString() {
- return jsonString;
- }
- }
-
- String getId();
-
- void setId(String id);
-
- String getName();
-
- void setName(String name);
-
- String getSummary();
-
- void setSummary(String summary);
-
- MediaLink getMedia();
-
- void setMedia(MediaLink media);
-
- String getPermalink();
-
- void setPermalink(String permalink);
-
- List<String> getType();
-
- void setType(List<String> type);
-
- ActivityObject getInReplyTo();
-
- void setInReplyTo(ActivityObject inReplyTo);
-
- List<ActivityObject> getAttached();
-
- void setAttached(List<ActivityObject> attached);
-
- List<ActivityObject> getReply();
-
- void setReply(List<ActivityObject> reply);
-
- List<ActivityObject> getReaction();
-
- void setReaction(List<ActivityObject> reaction);
-
- ActionLink getAction();
-
- void setAction(ActionLink action);
-
- List<String> getUpstreamDuplicateId();
-
- void setUpstreamDuplicateId(List<String> upstreamDuplicateId);
-
- List<String> getDownstreamDuplicateId();
-
- void setDownstreamDuplicateId(List<String> downstreamDuplicateId);
-
- String getStandardLink();
-
- void setStandardLink(String standardLink);
-}
\ No newline at end of file
+
+ /*
+ * Fields that represent JSON elements for an activity entry.
+ */
+ public static enum Field {
+ ID("id"),
+ NAME("name"),
+ SUMMARY("summary"),
+ MEDIA("media"),
+ PERMALINK("permalink"),
+ TYPE("type"),
+ IN_REPLY_TO("inReplyTo"),
+ ATTACHED("attached"),
+ REPLY("reply"),
+ REACTION("reaction"),
+ ACTION("action"),
+ UPSTREAM_DUPLICATE_ID("upstreamDuplicateId"),
+ DOWNSTREAM_DUPLICATE_ID("downstreamDuplicateId"),
+ STANDARD_LINK("standardLink");
+
+ /*
+ * The name of the JSON element.
+ */
+ private final String jsonString;
+
+ /**
+ * Constructs the field base for the JSON element.
+ *
+ * @param jsonString the name of the element
+ */
+ private Field(String jsonString) {
+ this.jsonString = jsonString;
+ }
+
+ /**
+ * Returns the name of the JSON element.
+ *
+ * @return String the name of the JSON element
+ */
+ public String toString() {
+ return jsonString;
+ }
+ }
+
+ /**
+ * Gets the absolute URI that uniquely identifies the object
+ *
+ * @return a non-null string
+ */
+ String getId();
+
+ /**
+ * Set the absolute URI that uniquely identifies the object
+ *
+ * @param id a non-null string
+ */
+ void setId(String id);
+
+ /**
+ * @return the human-readable name fo the object
+ */
+ String getName();
+
+ /**
+ * Sets the name
+ * @param name a human-readable name
+ */
+ void setName(String name);
+
+ /**
+ * Gets the human-readable summary for this object.
+ * @return the summary
+ */
+ String getSummary();
+
+ /**
+ * Sets the human-readable summary for this object.
+ *
+ * @param summary a summary
+ */
+ void setSummary(String summary);
+
+ /**
+ * Get the link to a media item
+ *
+ * @return a {@link org.apache.shindig.extras.as.opensocial.model.MediaLink} object.
+ */
+ MediaLink getMedia();
+
+ /**
+ * Set the link to a media item
+ *
+ * @param media a {@link org.apache.shindig.extras.as.opensocial.model.MediaLink} object.
+ */
+ void setMedia(MediaLink media);
+
+ /**
+ * Get the permanent link
+ *
+ * @return a permalink string, possibly null
+ */
+ String getPermalink();
+
+ /**
+ * Set the permanent link
+ *
+ * @param permalink a permalink string, possibly null
+ */
+ void setPermalink(String permalink);
+
+ /**
+ * Returns a list of Type strings
+ *
+ * @return a list of Type strings
+ */
+ List<String> getType();
+
+ /**
+ * set the list of Type strings
+ *
+ * @param type a list of Type strings
+ */
+ void setType(List<String> type);
+
+ /**
+ * Get the Activity this item is a response to
+ *
+ * @return a {@link org.apache.shindig.extras.as.opensocial.model.ActivityObject}
+ */
+ ActivityObject getInReplyTo();
+
+ /**
+ * Set the Activity this item is a response to
+ *
+ * @param inReplyTo a {@link org.apache.shindig.extras.as.opensocial.model.ActivityObject} object.
+ */
+ void setInReplyTo(ActivityObject inReplyTo);
+
+ /**
+ * Gets the list of Attached Activities for this entry
+ *
+ * @return a list of ActivityObjects
+ */
+ List<ActivityObject> getAttached();
+
+ /**
+ * Sets the list of Attached Activities for this entry
+ *
+ * @param attached a list of ActivityObjects
+ */
+ void setAttached(List<ActivityObject> attached);
+
+ /**
+ * Gets the list of reply Activities for this entry
+ *
+ * @return a list of ActivityObjects
+ */
+ List<ActivityObject> getReply();
+
+ /**
+ * Sets the list of reply Activities for this entry
+ *
+ * @param reply a list of ActivityObjects
+ */
+ void setReply(List<ActivityObject> reply);
+
+ /**
+ * Gets the list of reaction Activities for this entry
+ *
+ * @return a list of ActivityObjects
+ */
+ List<ActivityObject> getReaction();
+
+ /**
+ * Sets the list of reaction Activities for this entry
+ *
+ * @param reaction a list of ActivityObjects
+ */
+ void setReaction(List<ActivityObject> reaction);
+
+ /**
+ * Returns an ActionLink for this object
+ *
+ * @return a {@link org.apache.shindig.extras.as.opensocial.model.ActionLink} object.
+ */
+ ActionLink getAction();
+
+ /**
+ * Sets the ActionLink for this object
+ *
+ * @param action a {@link org.apache.shindig.extras.as.opensocial.model.ActionLink} object.
+ */
+ void setAction(ActionLink action);
+
+ /**
+ * Get the list of upstream duplicate Ids
+ *
+ * @return a list of strings
+ */
+ List<String> getUpstreamDuplicateId();
+
+ /**
+ * Set the list of upstream duplicate Ids
+ *
+ * @param upstreamDuplicateId a list of strings containing duplicate Ids
+ */
+ void setUpstreamDuplicateId(List<String> upstreamDuplicateId);
+
+ /**
+ * Get the list of downstream duplicate Ids
+ *
+ * @return a list of strings
+ */
+ List<String> getDownstreamDuplicateId();
+
+ /**
+ * Set the list of downstream duplicate Ids
+ *
+ * @param downstreamDuplicateId a list of strings containing duplicate Ids
+ */
+ void setDownstreamDuplicateId(List<String> downstreamDuplicateId);
+
+ /**
+ * Return a standard link string
+ *
+ * @return the standard link
+ */
+ String getStandardLink();
+
+ /**
+ * Set the standard link string
+ *
+ * @param standardLink the standard link
+ */
+ void setStandardLink(String standardLink);
+}
Modified: shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityStream.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityStream.java?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityStream.java (original)
+++ shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/ActivityStream.java Tue Sep 7 08:02:11 2010
@@ -25,7 +25,7 @@ import org.apache.shindig.protocol.model
import com.google.inject.ImplementedBy;
-/*
+/**
* Interface for an Activity Stream.
* <p>
* See the Activity Streams specification for more detail:
@@ -34,58 +34,106 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(ActivityStreamImpl.class)
@Exportablebean
public interface ActivityStream {
-
- /*
- * Fields that represent JSON elements for an activity entry.
- */
- public static enum Field {
- DISPLAY_NAME("displayName"),
- LANGUAGE("language"),
- ENTRIES("entries"),
- ID("id"),
- SUBJECT("subject");
-
- /*
- * The name of the JSON element.
- */
- private final String jsonString;
-
- /*
- * Constructs the field base for the JSON element.
- *
- * @param jsonString the name of the element
- */
- private Field(String jsonString) {
- this.jsonString = jsonString;
- }
-
- /*
- * Returns the name of the JSON element.
- *
- * @return String the name of the JSON element
- */
- public String toString() {
- return jsonString;
- }
- }
-
- void setId(String id);
-
- String getId();
-
- void setEntries(List<ActivityEntry> entries);
-
- List<ActivityEntry> getEntries();
-
- void setLanguage(String language);
-
- String getLanguage();
-
- void setSubject(String subject);
-
- String getSubject();
-
- void setDisplayName(String displayName);
-
- String getDisplayName();
-}
\ No newline at end of file
+
+ /*
+ * Fields that represent JSON elements for an activity entry.
+ */
+ public static enum Field {
+ DISPLAY_NAME("displayName"),
+ LANGUAGE("language"),
+ ENTRIES("entries"),
+ ID("id"),
+ SUBJECT("subject");
+
+ /*
+ * The name of the JSON element.
+ */
+ private final String jsonString;
+
+ /*
+ * Constructs the field base for the JSON element.
+ *
+ * @param jsonString the name of the element
+ */
+ private Field(String jsonString) {
+ this.jsonString = jsonString;
+ }
+
+ /*
+ * Returns the name of the JSON element.
+ *
+ * @return String the name of the JSON element
+ */
+ public String toString() {
+ return jsonString;
+ }
+ }
+
+ /**
+ * Sets the Id for this stream
+ * @param id a string
+ */
+ void setId(String id);
+
+ /**
+ * Return the id string
+ *
+ * @return a string
+ */
+ String getId();
+
+ /**
+ * Set the list of ActivityEntry objects
+ * @param entries a list of ActivityEntry
+ */
+ void setEntries(List<ActivityEntry> entries);
+
+ /**
+ * Get the list of ActivityEntry objects
+ *
+ * @return a list of ActivityEntry
+ */
+ List<ActivityEntry> getEntries();
+
+ /**
+ * Set the language for this stream
+ *
+ * @param language a language string
+ */
+ void setLanguage(String language);
+
+ /**
+ * Get the language for this stream
+ *
+ * @return a language string
+ */
+ String getLanguage();
+
+ /**
+ * Set the subject for this stream
+ *
+ * @param subject a subject string
+ */
+ void setSubject(String subject);
+
+ /**
+ * Get the subject for this stream
+ *
+ * @return a subject string
+ */
+ String getSubject();
+
+ /**
+ * Get the display name for this stream
+ *
+ * @param displayName a display name
+ */
+ void setDisplayName(String displayName);
+
+ /**
+ * Get the human readable name for this stream
+ *
+ * @return a display name
+ */
+ String getDisplayName();
+}
Modified: shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/MediaLink.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/MediaLink.java?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/MediaLink.java (original)
+++ shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/model/MediaLink.java Tue Sep 7 08:02:11 2010
@@ -24,61 +24,115 @@ import com.google.inject.ImplementedBy;
/*
* TODO: comment this class.
*/
+/**
+ * <p>MediaLink interface.</p>
+ *
+ */
@ImplementedBy(MediaLinkImpl.class)
@Exportablebean
public interface MediaLink {
- /*
- * Fields that represent the JSON elements.
- */
- public static enum Field {
- TARGET("target"),
- TYPE("type"),
- WIDTH("width"),
- HEIGHT("height"),
- DURATION("duration");
-
- /*
- * The name of the JSON element.
- */
- private final String jsonString;
-
- /*
- * Constructs the field base for the JSON element.
- *
- * @param jsonString the name of the element
- */
- private Field(String jsonString) {
- this.jsonString = jsonString;
- }
-
- /*
- * Returns the name of the JSON element.
- *
- * @return String the name of the JSON element
- */
- public String toString() {
- return jsonString;
- }
- }
-
- String getTarget();
-
- void setTarget(String target);
-
- String getType();
-
- void setType(String type);
-
- String getWidth();
-
- void setWidth(String width);
-
- String getHeight();
-
- void setHeight(String height);
-
- String getDuration();
-
- void setDuration(String duration);
+ /**
+ * Fields that represent the JSON elements.
+ */
+ public static enum Field {
+ TARGET("target"),
+ TYPE("type"),
+ WIDTH("width"),
+ HEIGHT("height"),
+ DURATION("duration");
+
+ /**
+ * The name of the JSON element.
+ */
+ private final String jsonString;
+
+ /**
+ * Constructs the field base for the JSON element.
+ *
+ * @param jsonString the name of the element
+ */
+ private Field(String jsonString) {
+ this.jsonString = jsonString;
+ }
+
+ /**
+ * Returns the name of the JSON element.
+ *
+ * @return String the name of the JSON element
+ */
+ public String toString() {
+ return jsonString;
+ }
+ }
+
+ /**
+ * Returns the target of this MediaLink
+ *
+ * @return a target
+ */
+ String getTarget();
+
+ /**
+ * Sets the target for this MediaLink
+ *
+ * @param target a target linke
+ */
+ void setTarget(String target);
+
+ /**
+ * Returns the type of the MediaLink
+ *
+ * @return a type
+ */
+ String getType();
+
+ /**
+ * Sets the type of the MediaLink
+ *
+ * @param type a type
+ */
+ void setType(String type);
+
+ /**
+ * <p>getWidth</p>
+ *
+ * @return a {@link java.lang.String} object.
+ */
+ String getWidth();
+
+ /**
+ * Sets the Width of this mediaLink
+ *
+ * @param width a width
+ */
+ void setWidth(String width);
+
+ /**
+ * Sets the Height of this mediaLink
+ *
+ * @return a height
+ */
+ String getHeight();
+
+ /**
+ * Sets the Height of this mediaLink
+ *
+ * @param height a height
+ */
+ void setHeight(String height);
+
+ /**
+ * Returns the duration of this mediaLink
+ *
+ * @return a duration
+ */
+ String getDuration();
+
+ /**
+ * Sets the duration of this mediaLink
+ *
+ * @param duration a duration
+ */
+ void setDuration(String duration);
}
Modified: shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandler.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandler.java?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandler.java (original)
+++ shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandler.java Tue Sep 7 08:02:11 2010
@@ -38,12 +38,22 @@ import com.google.common.collect.Immutab
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
+/**
+ * <p>ActivityStreamsHandler class.</p>
+ *
+ */
@Service(name = "activitystreams", path="/{userId}+/{groupId}/{appId}/{activitystream}/{activityEntryId}+")
public class ActivityStreamsHandler {
private final ActivityStreamService service;
private final ContainerConfig config;
+ /**
+ * <p>Constructor for ActivityStreamsHandler.</p>
+ *
+ * @param service a {@link org.apache.shindig.extras.as.opensocial.spi.ActivityStreamService} object.
+ * @param config a {@link org.apache.shindig.config.ContainerConfig} object.
+ */
@Inject
public ActivityStreamsHandler(ActivityStreamService service, ContainerConfig config) {
this.service = service;
@@ -54,6 +64,10 @@ public class ActivityStreamsHandler {
* Allowed end-points /activities/{userId}/@self/{actvityId}+
*
* examples: /activities/john.doe/@self/1
+ *
+ * @param request a {@link org.apache.shindig.social.opensocial.service.SocialRequestItem} object.
+ * @return a {@link java.util.concurrent.Future} object.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
@Operation(httpMethods="DELETE")
public Future<?> delete(SocialRequestItem request)
@@ -73,8 +87,12 @@ public class ActivityStreamsHandler {
* Allowed end-points /activities/{userId}/@self
*
* examples: /activities/john.doe/@self - postBody is an activity object
- *
+ *
* TODO: REST end-point
+ *
+ * @param request a {@link org.apache.shindig.social.opensocial.service.SocialRequestItem} object.
+ * @return a {@link java.util.concurrent.Future} object.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
@Operation(httpMethods="PUT", bodyParam = "activityEntry")
public Future<?> update(SocialRequestItem request) throws ProtocolException {
@@ -85,8 +103,12 @@ public class ActivityStreamsHandler {
* Allowed end-points /activities/{userId}/@self
*
* examples: /activities/john.doe/@self - postBody is an activity object
- *
+ *
* TODO: REST end-point
+ *
+ * @param request a {@link org.apache.shindig.social.opensocial.service.SocialRequestItem} object.
+ * @return a {@link java.util.concurrent.Future} object.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
@Operation(httpMethods="POST", bodyParam = "activityEntry")
public Future<?> create(SocialRequestItem request) throws ProtocolException {
@@ -110,6 +132,10 @@ public class ActivityStreamsHandler {
*
* examples: /activities/john.doe/@self/1 /activities/john.doe/@self
* /activities/john.doe,jane.doe/@friends
+ *
+ * @param request a {@link org.apache.shindig.social.opensocial.service.SocialRequestItem} object.
+ * @return a {@link java.util.concurrent.Future} object.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
@Operation(httpMethods="GET")
public Future<?> get(SocialRequestItem request)
@@ -143,6 +169,12 @@ public class ActivityStreamsHandler {
request.getFields(), options, request.getToken());
}
+ /**
+ * Return a list of supported fields for the ActivityStreams endpoint
+ *
+ * @param request a {@link org.apache.shindig.protocol.RequestItem} object.
+ * @return a List of supported fields
+ */
@Operation(httpMethods = "GET", path="/@supportedFields")
public List<Object> supportedFields(RequestItem request) {
// TODO: Would be nice if name in config matched name of service.
Modified: shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/spi/ActivityStreamService.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/spi/ActivityStreamService.java?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/spi/ActivityStreamService.java (original)
+++ shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/opensocial/spi/ActivityStreamService.java Tue Sep 7 08:02:11 2010
@@ -44,6 +44,7 @@ public interface ActivityStreamService {
* @param options The sorting/filtering/pagination options
* @param token A valid SecurityToken
* @return a response item with the list of activities.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
Future<RestfulCollection<ActivityEntry>> getActivityEntries(Set<UserId> userIds,
GroupId groupId, String appId, Set<String> fields, CollectionOptions options, SecurityToken token)
@@ -57,10 +58,11 @@ public interface ActivityStreamService {
* @param groupId Indicates whether to fetch activities for a group.
* @param appId The app id.
* @param fields The fields to return. Empty set implies all
- * @param options The sorting/filtering/pagination options
+ * @param options The sorting/filtering/pagination options
* @param activityIds The set of activity ids to fetch.
* @param token A valid SecurityToken
* @return a response item with the list of activities.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
Future<RestfulCollection<ActivityEntry>> getActivityEntries(UserId userId, GroupId groupId,
String appId, Set<String> fields, CollectionOptions options, Set<String> activityIds, SecurityToken token)
@@ -78,6 +80,7 @@ public interface ActivityStreamService {
* @param activityId The activity id to fetch.
* @param token A valid SecurityToken
* @return a response item with the list of activities.
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
Future<ActivityEntry> getActivityEntry(UserId userId, GroupId groupId, String appId,
Set<String> fields, String activityId, SecurityToken token)
@@ -92,6 +95,7 @@ public interface ActivityStreamService {
* @param activityIds A list of activity ids to delete.
* @param token A valid SecurityToken.
* @return a response item containing any errors
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
Future<Void> deleteActivityEntries(UserId userId, GroupId groupId, String appId,
Set<String> activityIds, SecurityToken token) throws ProtocolException;
@@ -107,6 +111,7 @@ public interface ActivityStreamService {
* @param activity The activity to create.
* @param token A valid SecurityToken
* @return a response item containing any errors
+ * @throws org.apache.shindig.protocol.ProtocolException if any.
*/
Future<Void> createActivityEntry(UserId userId, GroupId groupId, String appId,
Set<String> fields, ActivityEntry activity, SecurityToken token) throws ProtocolException;
Modified: shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/sample/ActivityStreamsJsonDbService.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/sample/ActivityStreamsJsonDbService.java?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/sample/ActivityStreamsJsonDbService.java (original)
+++ shindig/branches/2.0.x/extras/src/main/java/org/apache/shindig/extras/as/sample/ActivityStreamsJsonDbService.java Tue Sep 7 08:02:11 2010
@@ -41,11 +41,22 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;
+/**
+ * Sample Implementation of the ActivityStreams Service using a JSON
+ * database.
+ */
public class ActivityStreamsJsonDbService implements ActivityStreamService {
JsonDbOpensocialService jsonDb;
JSONObject db;
BeanConverter converter;
+ /**
+ * Create a new ActivityStreamsJsonDbService instance via Guice injection
+ *
+ * @param jsonDb a {@link org.apache.shindig.social.sample.spi.JsonDbOpensocialService} object.
+ * @param converter a {@link org.apache.shindig.protocol.conversion.BeanConverter} object
+ * annotated with "shindig.bean.converter.json".
+ */
@Inject
public ActivityStreamsJsonDbService(JsonDbOpensocialService jsonDb,
@Named("shindig.bean.converter.json")
@@ -63,69 +74,70 @@ public class ActivityStreamsJsonDbServic
// Are fields really needed here?
+ /** {@inheritDoc} */
public Future<Void> createActivityEntry(UserId userId, GroupId groupId, String appId,
- Set<String> fields, ActivityEntry activityEntry, SecurityToken token) throws ProtocolException {
- try {
- JSONObject jsonEntry = convertFromActivityEntry(activityEntry, fields);
- JSONObject jsonEntryObject = jsonEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString());
- if (!jsonEntryObject.has(ActivityObject.Field.ID.toString())) {
- jsonEntryObject.put(ActivityObject.Field.ID.toString(), System.currentTimeMillis());
- jsonEntry.put(ActivityEntry.Field.OBJECT.toString(), jsonEntryObject);
- }
-
- // TODO: bug fixed: jsonArray will not be null; will throw exception!
- // Fix in createActivity()
- JSONArray jsonArray;
- if(db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(userId.getUserId(token))) {
- jsonArray = db.getJSONObject(ACTIVITYSTREAMS_TABLE)
- .getJSONArray(userId.getUserId(token));
- } else {
- jsonArray = new JSONArray();
- db.getJSONObject(ACTIVITYSTREAMS_TABLE).put(userId.getUserId(token), jsonArray);
- }
- jsonArray.put(jsonEntry);
- return ImmediateFuture.newInstance(null);
- } catch (JSONException je) {
- throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
- je);
- }
+ Set<String> fields, ActivityEntry activityEntry, SecurityToken token) throws ProtocolException {
+ try {
+ JSONObject jsonEntry = convertFromActivityEntry(activityEntry, fields);
+ JSONObject jsonEntryObject = jsonEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString());
+ if (!jsonEntryObject.has(ActivityObject.Field.ID.toString())) {
+ jsonEntryObject.put(ActivityObject.Field.ID.toString(), System.currentTimeMillis());
+ jsonEntry.put(ActivityEntry.Field.OBJECT.toString(), jsonEntryObject);
+ }
+
+ // TODO: bug fixed: jsonArray will not be null; will throw exception!
+ // Fix in createActivity()
+ JSONArray jsonArray;
+ if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(userId.getUserId(token))) {
+ jsonArray = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(userId.getUserId(token));
+ } else {
+ jsonArray = new JSONArray();
+ db.getJSONObject(ACTIVITYSTREAMS_TABLE).put(userId.getUserId(token), jsonArray);
+ }
+ jsonArray.put(jsonEntry);
+ return ImmediateFuture.newInstance(null);
+ } catch (JSONException je) {
+ throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(), je);
+ }
}
+ /** {@inheritDoc} */
public Future<Void> deleteActivityEntries(UserId userId, GroupId groupId,
- String appId, Set<String> activityIds, SecurityToken token)
- throws ProtocolException {
- try {
- String user = userId.getUserId(token);
- if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
- JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
- if (activityEntries != null) {
- JSONArray newList = new JSONArray();
- for (int i = 0; i < activityEntries.length(); i++) {
- JSONObject activityEntry = activityEntries.getJSONObject(i);
- if (!activityIds.contains(activityEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString()).getString(ActivityObject.Field.ID.toString()))) {
- newList.put(activityEntry);
- }
- }
- db.getJSONObject(ACTIVITYSTREAMS_TABLE).put(user, newList);
- // TODO: This seems very odd that we return no useful response in this
- // case
- // There is no way to represent not-found
- // if (found) { ??
- // }
+ String appId, Set<String> activityIds, SecurityToken token) throws ProtocolException {
+ try {
+ String user = userId.getUserId(token);
+
+ if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
+ JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
+
+ if (activityEntries != null) {
+ JSONArray newList = new JSONArray();
+ for (int i = 0; i < activityEntries.length(); i++) {
+ JSONObject activityEntry = activityEntries.getJSONObject(i);
+ if (!activityIds.contains(activityEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString()).getString(ActivityObject.Field.ID.toString()))) {
+ newList.put(activityEntry);
+ }
+ }
+ db.getJSONObject(ACTIVITYSTREAMS_TABLE).put(user, newList);
+ // TODO: This seems very odd that we return no useful response in this
+ // case
+ // There is no way to represent not-found
+ // if (found) { ??
+ // }
}
- }
- // What is the appropriate response here??
- return ImmediateFuture.newInstance(null);
- } catch (JSONException je) {
- throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
- je);
- }
+ }
+ // What is the appropriate response here??
+ return ImmediateFuture.newInstance(null);
+ } catch (JSONException je) {
+ throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(), je);
+ }
}
+ /** {@inheritDoc} */
public Future<ActivityEntry> getActivityEntry(UserId userId, GroupId groupId,
- String appId, Set<String> fields, String activityId, SecurityToken token)
- throws ProtocolException {
- try {
+ String appId, Set<String> fields, String activityId, SecurityToken token)
+ throws ProtocolException {
+ try {
String user = userId.getUserId(token);
if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
@@ -136,93 +148,70 @@ public class ActivityStreamsJsonDbServic
if (actorId.equals(user)
&& activityEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString()).get(ActivityObject.Field.ID.toString()).toString().equals(activityId)) {
return ImmediateFuture.newInstance(jsonDb.filterFields(activityEntry, fields, ActivityEntry.class));
- }
+ }
}
}
throw new ProtocolException(HttpServletResponse.SC_BAD_REQUEST, "ActivityEntry not found");
} catch (JSONException je) {
- throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
- je);
+ throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(), je);
}
}
-
+
+ /** {@inheritDoc} */
public Future<RestfulCollection<ActivityEntry>> getActivityEntries(
- Set<UserId> userIds, GroupId groupId, String appId, Set<String> fields,
- CollectionOptions options, SecurityToken token)
- throws ProtocolException {
+ Set<UserId> userIds, GroupId groupId, String appId, Set<String> fields,
+ CollectionOptions options, SecurityToken token)
+ throws ProtocolException {
List<ActivityEntry> result = Lists.newArrayList();
-// // Retrieve activities from Lotus Connections
-// FeedParser parser;
-// try {
-// parser = new FeedParser();
-// ArrayList<JSONObject> activityEntries = parser.parseFeed("http://w3.ibm.com/connections/news/atom/stories/public");
-// for(JSONObject activityEntry : activityEntries) {
-// result.add(jsonDb.filterFields(activityEntry, fields, ActivityEntry.class));
-// }
-// } catch (ParserConfigurationException e) {
-// e.printStackTrace();
-// } catch (SAXException e) {
-// e.printStackTrace();
-// } catch (JSONException e) {
-// e.printStackTrace();
-// }
-
- try {
- Set<String> idSet = jsonDb.getIdSet(userIds, groupId, token);
- for (String id : idSet) {
- if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(id)) {
- JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(id);
- for (int i = 0; i < activityEntries.length(); i++) {
- JSONObject activityEntry = activityEntries.getJSONObject(i);
- result.add(jsonDb.filterFields(activityEntry, fields, ActivityEntry.class));
- // TODO: ActivityStreams don't have appIds
-// if (appId == null || !activitystream.has(ActivityStream.Field.APP_ID.toString())) {
-// result.add(jsonDb.filterFields(activitystream, fields, ActivityStream.class));
-// } else if (activitystream.get(ActivityStream.Field.APP_ID.toString()).equals(appId)) {
-// result.add(jsonDb.filterFields(activitystream, fields, ActivityStream.class));
-// }
- }
+ try {
+ Set<String> idSet = jsonDb.getIdSet(userIds, groupId, token);
+ for (String id : idSet) {
+ if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(id)) {
+ JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(id);
+ for (int i = 0; i < activityEntries.length(); i++) {
+ JSONObject activityEntry = activityEntries.getJSONObject(i);
+ result.add(jsonDb.filterFields(activityEntry, fields, ActivityEntry.class));
+ // TODO: ActivityStreams don't have appIds
}
}
- return ImmediateFuture.newInstance(new RestfulCollection<ActivityEntry>(result));
+ }
+ return ImmediateFuture.newInstance(new RestfulCollection<ActivityEntry>(result));
} catch (JSONException je) {
- throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
- je);
+ throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(), je);
}
}
-
+
+ /** {@inheritDoc} */
public Future<RestfulCollection<ActivityEntry>> getActivityEntries(
- UserId userId, GroupId groupId, String appId, Set<String> fields,
- CollectionOptions options, Set<String> activityIds, SecurityToken token)
- throws ProtocolException {
- List<ActivityEntry> result = Lists.newArrayList();
- try {
- String user = userId.getUserId(token);
- if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
- JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
- for (int i = 0; i < activityEntries.length(); i++) {
- JSONObject activityEntry = activityEntries.getJSONObject(i);
- JSONObject actor = new JSONObject(activityEntry.get(ActivityEntry.Field.ACTOR.toString()));
- String actorId = actor.get(ActivityObject.Field.ID.toString()).toString();
- if (actorId.equals(user)
- && activityIds.contains(activityEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString()).getString(ActivityObject.Field.ID.toString()).toString())) {
+ UserId userId, GroupId groupId, String appId, Set<String> fields,
+ CollectionOptions options, Set<String> activityIds, SecurityToken token)
+ throws ProtocolException {
+ List<ActivityEntry> result = Lists.newArrayList();
+ try {
+ String user = userId.getUserId(token);
+ if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
+ JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
+ for (int i = 0; i < activityEntries.length(); i++) {
+ JSONObject activityEntry = activityEntries.getJSONObject(i);
+ JSONObject actor = new JSONObject(activityEntry.get(ActivityEntry.Field.ACTOR.toString()));
+ String actorId = actor.get(ActivityObject.Field.ID.toString()).toString();
+ if (actorId.equals(user)
+ && activityIds.contains(activityEntry.getJSONObject(ActivityEntry.Field.OBJECT.toString()).getString(ActivityObject.Field.ID.toString()).toString())) {
result.add(jsonDb.filterFields(activityEntry, fields, ActivityEntry.class));
}
}
}
return ImmediateFuture.newInstance(new RestfulCollection<ActivityEntry>(result));
} catch (JSONException je) {
- throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
- je);
+ throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(), je);
}
}
private JSONObject convertFromActivityEntry(ActivityEntry activityEntry, Set<String> fields)
- throws JSONException {
- // TODO Not using fields yet
- return new JSONObject(converter.convertToString(activityEntry));
+ throws JSONException {
+ // TODO Not using fields yet
+ return new JSONObject(converter.convertToString(activityEntry));
}
-
}
Modified: shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/OpenAjax-mashup.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/OpenAjax-mashup.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/OpenAjax-mashup.js (original)
+++ shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/OpenAjax-mashup.js Tue Sep 7 08:02:11 2010
@@ -28,7 +28,7 @@ OpenAjax.hub = function() {
return /** @scope OpenAjax.hub */ {
implementer: "http://openajax.org",
- implVersion: "2.0.3",
+ implVersion: "2.0.4",
specVersion: "2.0",
implExtraData: {},
libraries: libs,
Modified: shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/feature.xml
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/feature.xml?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/feature.xml (original)
+++ shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/feature.xml Tue Sep 7 08:02:11 2010
@@ -17,7 +17,7 @@ KIND, either express or implied. See the
specific language governing permissions and limitations under the License.
-->
<feature>
- <name>org.openajax.hub-2.0.3</name>
+ <name>org.openajax.hub-2.0.4</name>
<dependency>rpc</dependency>
<gadget>
<script src="OpenAjax-mashup.js"/>
Modified: shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/iframe.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/iframe.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/iframe.js (original)
+++ shindig/branches/2.0.x/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/iframe.js Tue Sep 7 08:02:11 2010
@@ -26,10 +26,10 @@ OpenAjax.gadgets.rpctx = OpenAjax.gadget
// For now, we only use "oaaConfig" for the global "gadgets" object. If the "gadgets" global
// already exists, then there is no reason to check for "oaaConfig". In the future, if we use
// "oaaConfig" for other purposes, we'll need to remove the check for "!window.gadgets".
- if (!window.gadgets) {
+ if (typeof gadgets === 'undefined') {
// "oaaConfig" can be specified as a global object. If not found, then look for it as an
// attribute on the script line for the OpenAjax Hub JS file.
- if (!window.oaaConfig) {
+ if (typeof oaaConfig === 'undefined') {
var scripts = document.getElementsByTagName("script");
// match "OpenAjax-mashup.js", "OpenAjaxManagedHub-all*.js", "OpenAjaxManagedHub-core*.js"
var reHub = /openajax(?:managedhub-(?:all|core).*|-mashup)\.js$/i;
@@ -44,7 +44,7 @@ OpenAjax.gadgets.rpctx = OpenAjax.gadget
var config = scripts[i].getAttribute( "oaaConfig" );
if ( config ) {
try {
- window.oaaConfig = eval( "({ " + config + " })" );
+ oaaConfig = eval( "({ " + config + " })" );
} catch (e) {}
}
break;
@@ -52,8 +52,8 @@ OpenAjax.gadgets.rpctx = OpenAjax.gadget
}
}
- if (window.oaaConfig && window.oaaConfig.gadgetsGlobal) {
- window.gadgets = OpenAjax.gadgets;
+ if (typeof oaaConfig !== 'undefined' && oaaConfig.gadgetsGlobal) {
+ gadgets = OpenAjax.gadgets;
}
}
})();
@@ -529,13 +529,16 @@ OpenAjax.hub.IframeHubClient = function(
}
OpenAjax.hub.IframeContainer._rpcRouter.add( "..", this );
-// securityToken = generateSecurityToken( params, scope, log ); // XXX still necessary?
+// XXX The RPC layer initializes immediately on load, in the child (IframeHubClient). So it is too
+// late here to specify a security token for the RPC layer. At the moment, only the NIX
+// transport requires a child token (IFPC [aka FIM] is not supported).
+// securityToken = generateSecurityToken( params, scope, log );
var internalID = OpenAjax.gadgets.rpc.RPC_ID;
if ( ! internalID ) {
throw new Error( OpenAjax.hub.Error.WrongProtocol );
}
- clientID = decodeURIComponent( internalID.substr( internalID.indexOf("_") + 1 ) );
+ clientID = internalID.substr( internalID.indexOf("_") + 1 );
};
/*** HubClient interface ***/
@@ -802,7 +805,6 @@ OpenAjax.hub.IframeContainer._rpcRouter
return;
}
- id = encodeURIComponent( id );
do {
// a client with the specified ID already exists on this page;
// create a unique ID
@@ -818,9 +820,9 @@ OpenAjax.hub.IframeContainer._rpcRouter
securityCallback: onSecurityAlert
});
- rpcErrorsToOAA[ OpenAjax.gadgets.rpc.LOAD_TIMEOUT ] = OpenAjax.hub.SecurityAlert.LoadTimeout;
- rpcErrorsToOAA[ OpenAjax.gadgets.rpc.FRAME_PHISH ] = OpenAjax.hub.SecurityAlert.FramePhish;
- rpcErrorsToOAA[ OpenAjax.gadgets.rpc.FORGED_MSG ] = OpenAjax.hub.SecurityAlert.ForgedMsg;
+ rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_LOAD_TIMEOUT ] = OpenAjax.hub.SecurityAlert.LoadTimeout;
+ rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FRAME_PHISH ] = OpenAjax.hub.SecurityAlert.FramePhish;
+ rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FORGED_MSG ] = OpenAjax.hub.SecurityAlert.ForgedMsg;
this.add = _add;
return _add( id, receiver );
@@ -836,7 +838,7 @@ var rpcErrorsToOAA = {};
////////////////////////////////////////////////////////////////////////////////
-function generateSecurityToken( params, scope, log, overrideTokenLength ) {
+function generateSecurityToken( params, scope, log ) {
if ( ! OpenAjax.hub.IframeContainer._prng ) {
// create pseudo-random number generator with a default seed
var seed = new Date().getTime() + Math.random() + document.cookie;
@@ -854,7 +856,7 @@ function generateSecurityToken( params,
}
}
- var tokenLength = overrideTokenLength || (p && p.tokenLength) || 6;
+ var tokenLength = (p && p.tokenLength) || 6;
return OpenAjax.hub.IframeContainer._prng.nextRandomB64Str( tokenLength );
}
Modified: shindig/branches/2.0.x/extras/src/main/javascript/features-extras/pubsub-2/pubsub-2.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/extras/src/main/javascript/features-extras/pubsub-2/pubsub-2.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/extras/src/main/javascript/features-extras/pubsub-2/pubsub-2.js (original)
+++ shindig/branches/2.0.x/extras/src/main/javascript/features-extras/pubsub-2/pubsub-2.js Tue Sep 7 08:02:11 2010
@@ -21,19 +21,19 @@
*
* Uses OpenAjax Hub in order to do pubsub. Simple case is to do the following:
*
- * var gadget = gadgets.byId(__MODULE_ID__);
- * gadget.PubSub.subscribe(topic, callback);
- * ...
- * gadget.PubSub.publish(topic2, message);
+ * gadgets.util.registerOnLoadHandler(function() {
+ * gadgets.Hub.subscribe(topic, callback);
+ * // OR
+ * gadgets.Hub.publish(topic2, message);
+ * });
*
- * The <gadget instance>.PubSub object implements the OpenAjax.hub.HubClient
- * interface.
+ * The gadgets.Hub object implements the OpenAjax.hub.HubClient interface.
*
* By default, a HubClient is instantiated automatically by the pubsub-2 code.
* If the gadget wants to provide params to the HubClient constructor, it can
- * do so by setting values on <gadget instance>.PubSubSettings object:
+ * do so by setting values on gadgets.HubSettings object:
*
- * <gadget instance>.PubSubSettings = {
+ * gadgets.HubSettings = {
* // Parameters object for HubClient constructor.
* // @see http://openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.HubClient_constructor
* // @see http://openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.IframeHubClient_constructor
@@ -46,19 +46,15 @@
*
* For example, to set a security alert callback:
*
- * <gadget instance>.PubSubSettings.params.HubClient.onSecurityCallback =
+ * gadgets.HubSettings.params.HubClient.onSecurityCallback =
* function(alertSource, alertType) { ... };
*
* @see http://openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.HubClient
*/
(function() {
- var params = gadgets.util.getUrlParameters();
- var moduleId = params.mid || 0;
- var gadgetInstance = gadgets.byId(moduleId);
-
// Create a pubsub settings object
- gadgetInstance.PubSubSettings = {
+ gadgets.HubSettings = {
// Set default HubClient constructor params object
params: {
HubClient: {
@@ -66,27 +62,26 @@
alert( "Gadget stopped attempted security breach: " + alertType );
// Forces container to see Frame Phish alert and probably close this gadget
window.location.href = "about:blank";
- },
- scope: gadgetInstance
+ }
},
IframeHubClient: {}
}
};
- if (params.forcesecure) {
- gadgetInstance.PubSubSettings.params.IframeHubClient.requireParentVerifiable = true;
+ if (gadgets.util.getUrlParameters().forcesecure) {
+ gadgets.HubSettings.params.IframeHubClient.requireParentVerifiable = true;
}
// Register an onLoad handler
gadgets.util.registerOnLoadHandler(function() {
try {
// Create the HubClient.
- gadgetInstance.PubSub = new OpenAjax.hub.IframeHubClient(gadgetInstance.PubSubSettings.params);
+ gadgets.Hub = new OpenAjax.hub.IframeHubClient(gadgets.HubSettings.params);
// Connect to the ManagedHub
- gadgetInstance.PubSub.connect(gadgetInstance.PubSubSettings.onConnect);
+ gadgets.Hub.connect(gadgets.HubSettings.onConnect);
} catch(e) {
// TODO: error handling should be consistent with other OS gadget initialization error handling
- gadgets.error("ERROR creating or connecting IframeHubClient in gadgets.pubsub [" + e.message + "]");
+ gadgets.error("ERROR creating or connecting IframeHubClient in gadgets.Hub [" + e.message + "]");
}
});
})();
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/container/container.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/container/container.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/container/container.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/container/container.js Tue Sep 7 08:02:11 2010
@@ -42,14 +42,24 @@ shindig.container.Container = function(o
this.sites_ = {};
/**
- * @type {boolean}
+ * @type {string}
*/
- this.renderDebug_ = Boolean(shindig.container.util.getSafeJsonValue(config,
- shindig.container.ContainerConfig.RENDER_DEBUG, false));
+ this.renderDebugParam_ = String(shindig.container.util.getSafeJsonValue(
+ config, shindig.container.ContainerConfig.RENDER_DEBUG_PARAM,
+ shindig.container.ContainerConfig.RENDER_DEBUG));
/**
* @type {boolean}
*/
+ var param = window.__CONTAINER_URI.getQP(this.renderDebugParam_);
+ this.renderDebug_ = (typeof param === 'undefined')
+ ? Boolean(shindig.container.util.getSafeJsonValue(config,
+ shindig.container.ContainerConfig.RENDER_DEBUG, false))
+ : (param === '1');
+
+ /**
+ * @type {boolean}
+ */
this.renderTest_ = Boolean(shindig.container.util.getSafeJsonValue(config,
shindig.container.ContainerConfig.RENDER_TEST, false));
@@ -163,11 +173,7 @@ shindig.container.Container.prototype.na
*/
shindig.container.Container.prototype.closeGadget = function(site) {
var id = site.getId();
- var el = this.siteEls_[id];
site.close();
- if (el) {
- el.parentNode.removeChild(el);
- }
delete this.sites_[id];
this.unscheduleRefreshTokens_();
};
@@ -242,6 +248,8 @@ shindig.container.Container.prototype.on
shindig.container.ContainerConfig = {};
// Whether debug mode is turned on.
shindig.container.ContainerConfig.RENDER_DEBUG = 'renderDebug';
+// The debug param name to look for in container URL for per-request debugging.
+shindig.container.ContainerConfig.RENDER_DEBUG_PARAM = 'renderDebugParam';
// Whether test mode is turned on.
shindig.container.ContainerConfig.RENDER_TEST = 'renderTest';
// Security token refresh interval (in ms) for debugging.
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/container/gadget_holder.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/container/gadget_holder.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/container/gadget_holder.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/container/gadget_holder.js Tue Sep 7 08:02:11 2010
@@ -275,7 +275,7 @@ shindig.container.GadgetHolder.prototype
// TODO: Share this base container logic
// TODO: Two SD base URIs - one for container, one for gadgets
// Need to add parent at end of query due to gadgets parsing bug
- uri.setQP('parent', window.__CONTAINER_HOST);
+ uri.setQP('parent', window.__CONTAINER_URI.getOrigin());
// Remove existing social token if we have a new one
if (this.securityToken_) {
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/container/init.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/container/init.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/container/init.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/container/init.js Tue Sep 7 08:02:11 2010
@@ -40,12 +40,11 @@
}
function initializeGlobalVars() {
- var scriptUri = getLastScriptUri();
- if (scriptUri) {
- window.__API_HOST = scriptUri.getOrigin();
- window.__CONTAINER = scriptUri.getQP('container');
- }
- window.__CONTAINER_HOST = shindig.uri(document.location.href).getOrigin();
+ window.__API_URI = getLastScriptUri();
+ window.__CONTAINER = window.__API_URI
+ ? window.__API_URI.getQP('container')
+ : 'default';
+ window.__CONTAINER_URI = shindig.uri(document.location.href);
}
function getLastScriptUri() {
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/container/service.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/container/service.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/container/service.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/container/service.js Tue Sep 7 08:02:11 2010
@@ -34,7 +34,7 @@ shindig.container.Service = function(opt
* @type {string}
*/
this.apiHost_ = String(shindig.container.util.getSafeJsonValue(config,
- shindig.container.ServiceConfig.API_HOST, window.__API_HOST));
+ shindig.container.ServiceConfig.API_HOST, window.__API_URI.getOrigin()));
/**
* @type {string}
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/core.util/util.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/core.util/util.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/core.util/util.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/core.util/util.js Tue Sep 7 08:02:11 2010
@@ -332,9 +332,9 @@ gadgets['util'] = function() {
/**
* Attach an event listener to given DOM element (Not a gadget standard)
*
- * @param {object} elem DOM element on which to attach event.
+ * @param {Object} elem DOM element on which to attach event.
* @param {string} eventName Event type to listen for.
- * @param {function} callback Invoked when specified event occurs.
+ * @param {function()} callback Invoked when specified event occurs.
* @param {boolean} useCapture If true, initiates capture.
*/
'attachBrowserEvent': function(elem, eventName, callback, useCapture) {
@@ -350,9 +350,9 @@ gadgets['util'] = function() {
/**
* Remove event listener. (Shindig internal implementation only)
*
- * @param {object} elem DOM element from which to remove event.
+ * @param {Object} elem DOM element from which to remove event.
* @param {string} eventName Event type to remove.
- * @param {function} callback Listener to remove.
+ * @param {function()} callback Listener to remove.
* @param {boolean} useCapture Specifies whether listener being removed was added with
* capture enabled.
*/
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/rpc/nix.transport.js Tue Sep 7 08:02:11 2010
@@ -81,6 +81,7 @@ gadgets.rpctx.nix = function() {
// nix_channels['..'] while containers will have a channel
// per gadget stored under the gadget's ID.
var nix_channels = {};
+ var isForceSecure = {};
// Store the ready signal method for use on handshake complete.
var ready;
@@ -138,12 +139,59 @@ gadgets.rpctx.nix = function() {
NIX_SEARCH_PERIOD);
}
+ // Returns current window location, without hash values
+ function getLocationNoHash() {
+ var loc = window.location.href;
+ var idx = loc.indexOf('#');
+ if (idx == -1) {
+ return loc;
+ }
+ return loc.substring(0, idx);
+ }
+
+ // When "forcesecure" is set to true, use the relay file and a simple variant of IFPC to first
+ // authenticate the container and gadget with each other. Once that is done, then initialize
+ // the NIX protocol.
+ function setupSecureRelayToParent(rpctoken) {
+ // To the parent, transmit the child's URL, the passed in auth
+ // token, and another token generated by the child.
+ var childToken = (0x7FFFFFFF * Math.random()) | 0; // TODO expose way to have child set this value
+ var data = [
+ getLocationNoHash(),
+ childToken
+ ];
+ gadgets.rpc._createRelayIframe(rpctoken, data);
+
+ // listen for response from parent
+ var hash = window.location.href.split('#')[1] || '';
+
+ function relayTimer() {
+ var newHash = window.location.href.split('#')[1] || '';
+ if (newHash !== hash) {
+ clearInterval(relayTimerId);
+ var params = gadgets.util.getUrlParameters(window.location.href);
+ if (params.childtoken == childToken) {
+ // parent has been authenticated; now init NIX
+ conductHandlerSearch();
+ return;
+ }
+ // security error -- token didn't match
+ ready('..', false);
+ }
+ }
+ var relayTimerId = setInterval( relayTimer, 100 );
+ }
+
return {
getCode: function() {
return 'nix';
},
- isParentVerifiable: function() {
+ isParentVerifiable: function(opt_receiverId) {
+ // NIX is only parent verifiable if a receiver was setup with "forcesecure" set to TRUE.
+ if (opt_receiverId) {
+ return isForceSecure[opt_receiverId];
+ }
return false;
},
@@ -249,9 +297,14 @@ gadgets.rpctx.nix = function() {
return true;
},
- setup: function(receiverId, token) {
+ setup: function(receiverId, token, forcesecure) {
+ isForceSecure[receiverId] = !!forcesecure;
if (receiverId === '..') {
- conductHandlerSearch();
+ if (forcesecure) {
+ setupSecureRelayToParent(token);
+ } else {
+ conductHandlerSearch();
+ }
return true;
}
try {
@@ -274,6 +327,14 @@ gadgets.rpctx.nix = function() {
return false;
}
return true;
+ },
+
+ // data = [child URL, child auth token]
+ relayOnload: function(receiverId, data) {
+ // transmit childtoken back to child to complete authentication
+ var src = data[0] + '#childtoken=' + data[1];
+ var childIframe = document.getElementById(receiverId);
+ childIframe.src = src;
}
};
}();
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rpc.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rpc.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rpc.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/rpc/rpc.js Tue Sep 7 08:02:11 2010
@@ -112,6 +112,11 @@ gadgets.rpc = function() {
// shadowing of window.name by a "var name" declaration, or similar.
var rpcId = window.name;
+ var securityCallback = function() {};
+ var LOAD_TIMEOUT = 0;
+ var FRAME_PHISH = 1;
+ var FORGED_MSG = 2;
+
// Fallback transport is simply a dummy impl that emits no errors
// and logs info on calls it receives, to avoid undesired side-effects
// from falling back to IFPC or some other transport.
@@ -143,13 +148,6 @@ gadgets.rpc = function() {
params = gadgets.util.getUrlParameters();
}
- // Indicates whether to support early-message queueing, which is designed
- // to ensure that all messages sent by gadgets.rpc.call, irrespective
- // when they were made (before/after setupReceiver, before/after transport
- // setup complete), are sent. Hiding behind a query param to allow opt-in
- // for a time while this technique is proven.
- var useEarlyQueueing = (params['rpc_earlyq'] === "1");
-
/**
* Return a transport representing the best available cross-domain
* message-passing mechanism available to the browser.
@@ -189,8 +187,7 @@ gadgets.rpc = function() {
receiverTx[receiverId] = tx;
// If there are any early-queued messages, send them now directly through
- // the needed transport. This queue will only have contents if
- // useEarlyQueueing === true (see call method).
+ // the needed transport.
var earlyQueue = earlyRpcQueue[receiverId] || [];
for (var i = 0; i < earlyQueue.length; ++i) {
var rpc = earlyQueue[i];
@@ -203,6 +200,45 @@ gadgets.rpc = function() {
earlyRpcQueue[receiverId] = [];
}
+ // Track when this main page is closed or navigated to a different location
+ // ("unload" event).
+ // NOTE: The use of the "unload" handler here and for the relay iframe
+ // prevents the use of the in-memory page cache in modern browsers.
+ // See: https://developer.mozilla.org/en/using_firefox_1.5_caching
+ // See: http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
+ var mainPageUnloading = false,
+ hookedUnload = false;
+
+ function hookMainPageUnload() {
+ if ( hookedUnload ) {
+ return;
+ }
+ function onunload() {
+ mainPageUnloading = true;
+ }
+ gadgets.util.attachBrowserEvent(window, 'unload', onunload, false);
+ hookedUnload = true;
+ }
+
+ function relayOnload(targetId, sourceId, token, data, relayWindow) {
+ // Validate auth token.
+ if (!authToken[sourceId] || authToken[sourceId] !== token) {
+ gadgets.error("Invalid auth token. " + authToken[sourceId] + " vs " + token);
+ securityCallback(sourceId, FORGED_MSG);
+ }
+
+ relayWindow.onunload = function() {
+ if (setup[sourceId] && !mainPageUnloading) {
+ securityCallback(sourceId, FRAME_PHISH);
+ gadgets.rpc.removeReceiver(sourceId);
+ }
+ };
+ hookMainPageUnload();
+
+ data = gadgets.json.parse(decodeURIComponent(data));
+ transport.relayOnload(sourceId, data);
+ }
+
/**
* Helper function to process an RPC request
* @param {Object} rpc RPC request object
@@ -225,8 +261,8 @@ gadgets.rpc = function() {
// We don't do type coercion here because all entries in the authToken
// object are strings, as are all url params. See setupReceiver(...).
if (authToken[rpc.f] !== rpc.t) {
- throw new Error("Invalid auth token. " +
- authToken[rpc.f] + " vs " + rpc.t);
+ gadgets.error("Invalid auth token. " + authToken[rpc.f] + " vs " + rpc.t);
+ securityCallback(rpc.f, FORGED_MSG);
}
}
@@ -371,7 +407,7 @@ gadgets.rpc = function() {
* RPC mechanism. Gadgets, in turn, will complete the setup
* of the channel once they send their first messages.
*/
- function setupFrame(frameId, token) {
+ function setupFrame(frameId, token, forcesecure) {
if (setup[frameId] === true) {
return;
}
@@ -382,7 +418,7 @@ gadgets.rpc = function() {
var tgtFrame = document.getElementById(frameId);
if (frameId === '..' || tgtFrame != null) {
- if (transport.setup(frameId, token) === true) {
+ if (transport.setup(frameId, token, forcesecure) === true) {
setup[frameId] = true;
return;
}
@@ -390,7 +426,7 @@ gadgets.rpc = function() {
if (setup[frameId] !== true && setup[frameId]++ < SETUP_FRAME_MAX_TRIES) {
// Try again in a bit, assuming that frame will soon exist.
- window.setTimeout(function() { setupFrame(frameId, token) },
+ window.setTimeout(function() { setupFrame(frameId, token, forcesecure) },
SETUP_FRAME_TIMEOUT);
} else {
// Fail: fall back for this gadget.
@@ -451,6 +487,17 @@ gadgets.rpc = function() {
* @deprecated
*/
function setRelayUrl(targetId, url, opt_useLegacy) {
+ // make URL absolute if necessary
+ if (!/http(s)?:\/\/.+/.test(url)) {
+ if (url.indexOf("//") == 0) {
+ url = window.location.protocol + url;
+ } else if (url.charAt(0) == '/') {
+ url = window.location.protocol + "//" + window.location.host + url;
+ } else if (url.indexOf("://") == -1) {
+ // Assumed to be schemaless. Default to current protocol.
+ url = window.location.protocol + "//" + url;
+ }
+ }
relayUrl[targetId] = url;
useLegacyProtocol[targetId] = !!opt_useLegacy;
}
@@ -474,7 +521,7 @@ gadgets.rpc = function() {
* @member gadgets.rpc
* @deprecated
*/
- function setAuthToken(targetId, token) {
+ function setAuthToken(targetId, token, forcesecure) {
token = token || "";
// Coerce token to a String, ensuring that all authToken values
@@ -482,10 +529,10 @@ gadgets.rpc = function() {
// in the process(rpc) method.
authToken[targetId] = String(token);
- setupFrame(targetId, token);
+ setupFrame(targetId, token, forcesecure);
}
- function setupContainerGadgetContext(rpctoken) {
+ function setupContainerGadgetContext(rpctoken, opt_forcesecure) {
/**
* Initializes gadget to container RPC params from the provided configuration.
*/
@@ -525,7 +572,8 @@ gadgets.rpc = function() {
}
// Sets the auth token and signals transport to setup connection to container.
- setAuthToken('..', rpctoken);
+ var forceSecure = opt_forcesecure || params.forcesecure || false;
+ setAuthToken('..', rpctoken, forceSecure);
}
var requiredConfig = {
@@ -534,19 +582,20 @@ gadgets.rpc = function() {
gadgets.config.register("rpc", requiredConfig, init);
}
- function setupContainerGenericIframe(rpctoken, opt_parent) {
+ function setupContainerGenericIframe(rpctoken, opt_parent, opt_forcesecure) {
// Generic child IFRAME setting up connection w/ its container.
// Use the opt_parent param if provided, or the "parent" query param
// if found -- otherwise, do nothing since this call might be initiated
// automatically at first, then actively later in IFRAME code.
+ var forcesecure = opt_forcesecure || params.forcesecure || false;
var parent = opt_parent || params.parent;
if (parent) {
setRelayUrl('..', parent);
- setAuthToken('..', rpctoken);
+ setAuthToken('..', rpctoken, forcesecure);
}
}
- function setupChildIframe(gadgetId, opt_frameurl, opt_authtoken) {
+ function setupChildIframe(gadgetId, opt_frameurl, opt_authtoken, opt_forcesecure) {
if (!gadgets.util) {
return;
}
@@ -564,7 +613,8 @@ gadgets.rpc = function() {
// The auth token is parsed from child params (rpctoken) or overridden.
var childParams = gadgets.util.getUrlParameters(childIframe.src);
var rpctoken = opt_authtoken || childParams.rpctoken;
- setAuthToken(gadgetId, rpctoken);
+ var forcesecure = opt_forcesecure || childParams.forcesecure;
+ setAuthToken(gadgetId, rpctoken, forcesecure);
}
/**
@@ -609,23 +659,30 @@ gadgets.rpc = function() {
* @param {string} targetId
* @param {string=} opt_receiverurl
* @param {string=} opt_authtoken
+ * @param {boolean=} opt_forcesecure
*/
- function setupReceiver(targetId, opt_receiverurl, opt_authtoken) {
+ function setupReceiver(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure) {
if (targetId === '..') {
// Gadget/IFRAME to container.
var rpctoken = opt_authtoken || params.rpctoken || params.ifpctok || "";
if (window['__isgadget'] === true) {
- setupContainerGadgetContext(rpctoken);
+ setupContainerGadgetContext(rpctoken, opt_forcesecure);
} else {
- setupContainerGenericIframe(rpctoken, opt_receiverurl);
+ setupContainerGenericIframe(rpctoken, opt_receiverurl, opt_forcesecure);
}
} else {
// Container to child.
- setupChildIframe(targetId, opt_receiverurl, opt_authtoken);
+ setupChildIframe(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure);
}
}
return /** @scope gadgets.rpc */ {
+ config: function(config) {
+ if (typeof config.securityCallback === 'function') {
+ securityCallback = config.securityCallback;
+ }
+ },
+
/**
* Registers an RPC service.
* @param {string} serviceName Service name to register.
@@ -747,7 +804,7 @@ gadgets.rpc = function() {
// Attempt to make call via a cross-domain transport.
// Retrieve the transport for the given target - if one
// target is misconfigured, it won't affect the others.
- var channel = receiverTx[targetId] ? receiverTx[targetId] : transport;
+ var channel = receiverTx[targetId];
if (!channel) {
// Not set up yet. Enqueue the rpc for such time as it is.
@@ -797,6 +854,16 @@ gadgets.rpc = function() {
setAuthToken: setAuthToken,
setupReceiver: setupReceiver,
getAuthToken: getAuthToken,
+
+ // Note: Does not delete iframe
+ removeReceiver: function(receiverId) {
+ delete relayUrl[receiverId];
+ delete useLegacyProtocol[receiverId];
+ delete authToken[receiverId];
+ delete setup[receiverId];
+ delete sameDomain[receiverId];
+ delete receiverTx[receiverId];
+ },
/**
* Gets the RPC relay mechanism.
@@ -820,10 +887,12 @@ gadgets.rpc = function() {
* @member gadgets.rpc
* @deprecated
*/
- receive: function(fragment) {
+ receive: function(fragment, otherWindow) {
if (fragment.length > 4) {
process(gadgets.json.parse(
decodeURIComponent(fragment[fragment.length - 1])));
+ } else {
+ relayOnload.apply(null, fragment.concat(otherWindow));
}
},
@@ -844,6 +913,21 @@ gadgets.rpc = function() {
// see docs above
getOrigin: getOrigin,
+ getReceiverOrigin: function(receiverId) {
+ var channel = receiverTx[receiverId];
+ if (!channel) {
+ // not set up yet
+ return null;
+ }
+ if (!channel.isParentVerifiable(receiverId)) {
+ // given transport cannot verify receiver origin
+ return null;
+ }
+ var origRelay = gadgets.rpc.getRelayUrl(receiverId) ||
+ gadgets.util.getUrlParameters().parent;
+ return gadgets.rpc.getOrigin(origRelay);
+ },
+
/**
* Internal-only method used to initialize gadgets.rpc.
* @member gadgets.rpc
@@ -863,9 +947,51 @@ gadgets.rpc = function() {
/** Returns the window keyed by the ID. null/".." for parent, else child */
_getTargetWin: getTargetWin,
+ /** Create an iframe for loading the relay URL. Used by child only. */
+ _createRelayIframe: function(token, data) {
+ var relay = gadgets.rpc.getRelayUrl('..');
+ if (!relay) {
+ return;
+ }
+
+ // Format: #targetId & sourceId & authToken & data
+ var src = relay + '#..&' + rpcId + '&' + token + '&' +
+ encodeURIComponent(gadgets.json.stringify(data));
+
+ var iframe = document.createElement('iframe');
+ iframe.style.border = iframe.style.width = iframe.style.height = '0px';
+ iframe.style.visibility = 'hidden';
+ iframe.style.position = 'absolute';
+
+ function appendFn() {
+ // Append the iframe.
+ document.body.appendChild(iframe);
+
+ // Set the src of the iframe to 'about:blank' first and then set it
+ // to the relay URI. This prevents the iframe from maintaining a src
+ // to the 'old' relay URI if the page is returned to from another.
+ // In other words, this fixes the bfcache issue that causes the iframe's
+ // src property to not be updated despite us assigning it a new value here.
+ iframe.src = 'javascript:"<html></html>"';
+ iframe.src = src;
+ }
+
+ if (document.body) {
+ appendFn();
+ } else {
+ gadgets.util.registerOnLoadHandler(function() { appendFn(); });
+ }
+
+ return iframe;
+ },
+
ACK: ACK,
- RPC_ID: rpcId
+ RPC_ID: rpcId,
+
+ SEC_ERROR_LOAD_TIMEOUT: LOAD_TIMEOUT,
+ SEC_ERROR_FRAME_PHISH: FRAME_PHISH,
+ SEC_ERROR_FORGED_MSG : FORGED_MSG
};
}();
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/rpc/wpm.transport.js
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/rpc/wpm.transport.js?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/rpc/wpm.transport.js (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/rpc/wpm.transport.js Tue Sep 7 08:02:11 2010
@@ -44,7 +44,64 @@ gadgets.rpctx = gadgets.rpctx || {};
if (!gadgets.rpctx.wpm) { // make lib resilient to double-inclusion
gadgets.rpctx.wpm = function() {
- var ready;
+ var process, ready;
+ var postMessage;
+ var pmSync = false;
+ var pmEventDomain = false;
+ var isForceSecure = false;
+
+ // Some browsers (IE, Opera) have an implementation of postMessage that is
+ // synchronous, although HTML5 specifies that it should be asynchronous. In
+ // order to make all browsers behave consistently, we run a small test to detect
+ // if postMessage is asynchronous or not. If not, we wrap calls to postMessage
+ // in a setTimeout with a timeout of 0.
+ // Also, Opera's "message" event does not have an "origin" property (at least,
+ // it doesn't in version 9.64; presumably, it will in version 10). If
+ // event.origin does not exist, use event.domain. The other difference is that
+ // while event.origin looks like <scheme>://<hostname>:<port>, event.domain
+ // consists only of <hostname>.
+ //
+ function testPostMessage() {
+ var hit = false;
+
+ function receiveMsg(event) {
+ if (event.data == "postmessage.test") {
+ hit = true;
+ if (typeof event.origin === "undefined") {
+ pmEventDomain = true;
+ }
+ }
+ }
+
+ gadgets.util.attachBrowserEvent(window, "message", receiveMsg, false);
+ window.postMessage("postmessage.test", "*");
+
+ // if 'hit' is true here, then postMessage is synchronous
+ if (hit) {
+ pmSync = true;
+ }
+
+ gadgets.util.removeBrowserEvent(window, "message", receiveMsg, false);
+ }
+
+ function onmessage(packet) {
+ var rpc = gadgets.json.parse(packet.data);
+ if (isForceSecure) {
+ if (!rpc || !rpc.f) {
+ return;
+ }
+
+ // for security, check origin against expected value
+ var origRelay = gadgets.rpc.getRelayUrl(rpc.f) ||
+ gadgets.util.getUrlParameters()["parent"];
+ var origin = gadgets.rpc.getOrigin(origRelay);
+ if (!pmEventDomain ? packet.origin !== origin :
+ packet.domain !== /^.+:\/\/([^:]+).*/.exec( origin )[1]) {
+ return;
+ }
+ }
+ process(rpc);
+ }
return {
getCode: function() {
@@ -56,11 +113,21 @@ gadgets.rpctx.wpm = function() {
},
init: function(processFn, readyFn) {
+ process = processFn;
ready = readyFn;
- var onmessage = function(packet) {
- // TODO validate packet.domain for security reasons
- processFn(gadgets.json.parse(packet.data));
- };
+
+ testPostMessage();
+ if (!pmSync) {
+ postMessage = function(win, msg, origin) {
+ win.postMessage(msg, origin);
+ };
+ } else {
+ postMessage = function(win, msg, origin) {
+ window.setTimeout( function() {
+ win.postMessage(msg, origin);
+ }, 0);
+ };
+ }
// Set up native postMessage handler.
gadgets.util.attachBrowserEvent(window, 'message', onmessage, false);
@@ -69,11 +136,16 @@ gadgets.rpctx.wpm = function() {
return true;
},
- setup: function(receiverId, token) {
+ setup: function(receiverId, token, forceSecure) {
+ isForceSecure = forceSecure;
// If we're a gadget, send an ACK message to indicate to container
// that we're ready to receive messages.
if (receiverId === '..') {
- gadgets.rpc.call(receiverId, gadgets.rpc.ACK);
+ if (isForceSecure) {
+ gadgets.rpc._createRelayIframe(token);
+ } else {
+ gadgets.rpc.call(receiverId, gadgets.rpc.ACK);
+ }
}
return true;
},
@@ -85,12 +157,16 @@ gadgets.rpctx.wpm = function() {
gadgets.util.getUrlParameters()["parent"];
var origin = gadgets.rpc.getOrigin(origRelay);
if (origin) {
- targetWin.postMessage(gadgets.json.stringify(rpc), origin);
+ postMessage(targetWin, gadgets.json.stringify(rpc), origin);
} else {
gadgets.error("No relay set (used as window.postMessage targetOrigin)" +
", cannot send cross-domain message");
}
return true;
+ },
+
+ relayOnload: function(receiverId, data) {
+ ready(receiverId, true);
}
};
}();
Modified: shindig/branches/2.0.x/features/src/main/javascript/features/shindig.container/feature.xml
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/features/src/main/javascript/features/shindig.container/feature.xml?rev=993268&r1=993267&r2=993268&view=diff
==============================================================================
--- shindig/branches/2.0.x/features/src/main/javascript/features/shindig.container/feature.xml (original)
+++ shindig/branches/2.0.x/features/src/main/javascript/features/shindig.container/feature.xml Tue Sep 7 08:02:11 2010
@@ -27,6 +27,7 @@ A map of view names to view attributes.
<dependency>globals</dependency>
<dependency>rpc</dependency>
<dependency>osapi</dependency>
+ <dependency>shindig.uri.ext</dependency>
<container>
<script src="util.js"/>
<script src="cookies.js"/>