You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by lr...@apache.org on 2008/07/08 23:00:56 UTC
svn commit: r674954 [1/3] - in /incubator/shindig/trunk: ./ config/
java/social-api/src/main/java/org/apache/shindig/social/abdera/
java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/
java/social-api/src/main/java/org/apache/shindig/so...
Author: lryan
Date: Tue Jul 8 14:00:54 2008
New Revision: 674954
URL: http://svn.apache.org/viewvc?rev=674954&view=rev
Log:
Apply https://issues.apache.org/jira/browse/SHINDIG-422
Added:
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RawResponseContext.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRequestContext.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/AbstractSocialEntityCollectionAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/ActivityAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/DataAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/PersonAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/PersonJsonAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/SimpleJsonAdapter.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialRequestContextTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/atom/
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/atom/RestfulAtomActivityTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/atom/RestfulAtomDataTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/atom/RestfulAtomPeopleTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/json/
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/json/PersonJsonAdapterTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/json/RestfulJsonActivityTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/json/RestfulJsonDataTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/json/RestfulJsonPeopleTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanUtil.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/model/
incubator/shindig/trunk/javascript/sampledata/canonicaldb.bak.json
incubator/shindig/trunk/javascript/sampledata/examplebatchrequest.json
Removed:
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/AbstractSocialEntityCollectionAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/ActivityAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/DataAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PersonAdapter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SimpleJsonAdapter.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomActivityTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomDataTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomPeopleTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulJsonActivityTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulJsonDataTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulJsonPeopleTest.java
Modified:
incubator/shindig/trunk/config/container.js
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRouteManager.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/JSONFilter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/util/ValidRequestFilter.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/PeopleService.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/SampleContainerRouteManager.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialApiProviderTestFixture.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/ValidRequestTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/samplecontainer/SampleContainerRoutesTest.java
incubator/shindig/trunk/pom.xml
Modified: incubator/shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/config/container.js?rev=674954&r1=674953&r2=674954&view=diff
==============================================================================
--- incubator/shindig/trunk/config/container.js (original)
+++ incubator/shindig/trunk/config/container.js Tue Jul 8 14:00:54 2008
@@ -109,7 +109,7 @@
// Otherwise, uses the json wire format.
// If you are using the default Shindig setup and want to use rest, don't
// forget to change the "path" config to /social/rest
- "useRestful" : false
+ "useRestful" : true
}
}}
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RawResponseContext.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RawResponseContext.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RawResponseContext.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RawResponseContext.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,93 @@
+package org.apache.shindig.social.abdera;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+import org.apache.abdera.protocol.server.context.SimpleResponseContext;
+import org.apache.abdera.util.EntityTag;
+import org.apache.commons.io.IOUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Date;
+
+
+/**
+ * A ResponseContext implementation that use a generic writer.
+ */
+public class RawResponseContext
+ extends SimpleResponseContext {
+
+ private InputStream in;
+
+ public RawResponseContext(
+ InputStream in,
+ EntityTag etag,
+ int status) {
+ this.in = in;
+ this.status = status;
+ setEntityTag(etag);
+ }
+
+ public RawResponseContext(
+ InputStream in,
+ int status) {
+ this.in = in;
+ this.status = status;
+ }
+
+ public RawResponseContext(
+ InputStream in,
+ Date lastmodified,
+ int status) {
+ this.in = in;
+ this.status = status;
+ setLastModified(lastmodified);
+ }
+
+ public RawResponseContext(String content, int status) throws UnsupportedEncodingException {
+ this.in = new ByteArrayInputStream(content.getBytes("UTF-8"));
+ this.status = status;
+ }
+
+ public boolean hasEntity() {
+ return in != null;
+ }
+
+ public void writeTo(
+ OutputStream out)
+ throws IOException {
+ if (hasEntity()) {
+ if (in != null) {
+ IOUtils.copy(in, out);
+ }
+ }
+ }
+
+ protected void writeEntity(
+ Writer out)
+ throws IOException {
+ if (in != null) {
+ IOUtils.copy(in, out);
+ }
+ }
+}
Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java?rev=674954&r1=674953&r2=674954&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java Tue Jul 8 14:00:54 2008
@@ -17,6 +17,12 @@
*/
package org.apache.shindig.social.abdera;
+import org.apache.shindig.social.abdera.util.ValidRequestFilter;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* The RequestUrlTemplate enum standardizes the names and descriptions of the
* URL templates as defined in the RESTful API spec.
@@ -31,46 +37,68 @@
public enum RequestUrlTemplate {
// People
- PROFILES_OF_CONNECTIONS_OF_USER("Profiles of Connections of User",
- "people/:uid/@all", "/people/{guid}/@all"),
- PROFILES_OF_FRIENDS_OF_USER("Profiles of Friends of User",
- "people/:uid/@friends", "/people/{guid}/@friends"),
- PROFILES_IN_GROUP_OF_USER("Profiles in Group of User",
- "people/:uid/:gid", "/people/{guid}/{groupid}"),
- PROFILE_OF_CONNECTION_OF_USER("Profile of Connection of User",
- "people/:uid/@all/:pid", "/people/{guid}/@all/{pid}"),
- PROFILE_OF_USER("Profile of User",
- "people/:uid/@self", "/people/{guid}/@self"),
- PROFILE_OF_REQUESTER("Profile of Requester",
- "people/@me/@self", "/people/@me/@self"),
+ JSON_PROFILES_OF_CONNECTIONS_OF_USER("Profiles of Connections of User in JSON format",
+ "people/:uid/@all", ValidRequestFilter.Format.JSON),
+ ATOM_PROFILES_OF_CONNECTIONS_OF_USER("Profiles of Connections of User in ATOM format",
+ "people/:uid/@all", ValidRequestFilter.Format.ATOM),
+
+ JSON_PROFILES_OF_FRIENDS_OF_USER("Profiles of Friends of User in JSON format",
+ "people/:uid/@friends", ValidRequestFilter.Format.JSON),
+ ATOM_PROFILES_OF_FRIENDS_OF_USER("Profiles of Friends of User in ATOM format",
+ "people/:uid/@friends", ValidRequestFilter.Format.ATOM),
+
+ JSON_PROFILES_IN_GROUP_OF_USER("Profiles in Group of User in JSON format",
+ "people/:uid/:gid", ValidRequestFilter.Format.JSON),
+ ATOM_PROFILES_IN_GROUP_OF_USER("Profiles in Group of User in ATOM format",
+ "people/:uid/:gid", ValidRequestFilter.Format.ATOM),
+
+ JSON_PROFILE_OF_CONNECTION_OF_USER("Profile of Connection of User in the JSON format",
+ "people/:uid/@all/:pid", ValidRequestFilter.Format.JSON),
+ ATOM_PROFILE_OF_CONNECTION_OF_USER("Profile of Connection of User in the ATOM format",
+ "people/:uid/@all/:pid", ValidRequestFilter.Format.ATOM),
+
+ JSON_PROFILE_OF_USER("Profile of User in JSON format",
+ "people/:uid/@self", ValidRequestFilter.Format.JSON),
+ ATOM_PROFILE_OF_USER("Profile of User in ATOM format",
+ "people/:uid/@self", ValidRequestFilter.Format.ATOM),
+
+ JSON_PROFILE_OF_REQUESTER("Profile of Requester in JSON format",
+ "people/@me/@self", ValidRequestFilter.Format.JSON),
+ ATOM_PROFILE_OF_REQUESTER("Profile of Requester in ATOM format",
+ "people/@me/@self", ValidRequestFilter.Format.ATOM),
+
// Activities
ACTIVITIES_OF_USER("Activities of User",
- "activities/:uid/@self", "/activities/{uid}/@self"),
+ "activities/:uid/@self", null),
ACTIVITIES_OF_FRIENDS_OF_USER("Activities of Friends of User",
- "activities/:uid/@friends", "/activities/{uid}/@friends"),
+ "activities/:uid/@friends", null),
ACTIVITIES_OF_GROUP_OF_USER("Activities of Group of User",
- "activities/:uid/:gid", "/activities/{uid}/{gid}"),
+ "activities/:uid/:gid", null),
ACTIVITY_OF_USER("Activity of User",
- "activities/:uid/@self/:aid", "/activities/{uid}/@self/{aid}"),
+ "activities/:uid/@self/:aid", null),
// AppData
APPDATA_OF_APP_OF_USER("AppData of App of User",
- "appdata/:uid/@self/:aid", "/appdata/{uid}/@self/{aid}"),
+ "appdata/:uid/@self/:aid", null),
APPDATA_OF_FRIENDS_OF_USER("AppData of Friends of User",
- "appdata/:uid/@friends/:aid", "/appdata/{uid}/@friends/{aid}");
+ "appdata/:uid/@friends/:aid", null);
- private String description;
- private String routePattern;
- private String urlTemplate;
+ private final String description;
+ private final String routePattern;
+ private final ValidRequestFilter.Format formatRestriction;
private RequestUrlTemplate(String description, String routePattern,
- String urlTemplate) {
+ ValidRequestFilter.Format format) {
this.description = description;
this.routePattern = routePattern;
- this.urlTemplate = urlTemplate;
+ this.formatRestriction = format;
}
@Override
public String toString() {
+ return getDescription();
+ }
+
+ public String getDescription() {
return description;
}
@@ -78,11 +106,35 @@
return routePattern;
}
- public String getUrlTemplate() {
- return urlTemplate;
+ public ValidRequestFilter.Format getFormatRestriction() {
+ return formatRestriction;
+ }
+
+ //Reverse Lookup for the description Field
+ private static final Map<String, RequestUrlTemplate> lookupByDescription =
+ new HashMap<String, RequestUrlTemplate>();
+
+ static {
+ for (RequestUrlTemplate t : EnumSet.allOf(RequestUrlTemplate.class)) {
+ lookupByDescription.put(t.getDescription(), t);
+ }
}
- public static RequestUrlTemplate getValue(String value) {
- return valueOf(value.replaceAll(" ", "_").toUpperCase());
+ public static RequestUrlTemplate getByDescription(String description) {
+ return lookupByDescription.get(description);
}
+
+ //Reverse Lookup for the routePattern Field
+ private static final Map<String, RequestUrlTemplate> lookupByRoutePattern =
+ new HashMap<String, RequestUrlTemplate>();
+
+ static {
+ for (RequestUrlTemplate t : EnumSet.allOf(RequestUrlTemplate.class))
+ lookupByRoutePattern.put(t.getRoutePattern(), t);
+ }
+
+ public static RequestUrlTemplate getByRoutePattern(String pattern) {
+ return lookupByRoutePattern.get(pattern);
+ }
+
}
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRequestContext.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRequestContext.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRequestContext.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRequestContext.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,67 @@
+package org.apache.shindig.social.abdera;
+
+import com.google.common.collect.Sets;
+
+import org.apache.shindig.social.dataservice.PersonService;
+import org.apache.shindig.social.opensocial.model.Person;
+
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.context.RequestContextWrapper;
+
+import java.util.Set;
+
+public class SocialRequestContext extends RequestContextWrapper {
+
+ // Common OpenSocial RESTful parameters
+ public static final String START_INDEX = "startIndex";
+ public static final String COUNT = "count";
+ public static final String ORDER_BY = "orderBy";
+ public static final String FILTER_BY = "filterBy";
+ public static final String FIELDS = "fields";
+ public static final String SECURITY_TOKEN_PARAM = "st";
+
+ // OpenSocial parameter defaults
+ public static final int DEFAULT_START_INDEX = 0;
+ public static final int DEFAULT_COUNT = 20;
+ public static final Set<String> DEFAULT_PERSON_FIELDS = Sets.newHashSet(
+ Person.Field.ID.toString(),
+ Person.Field.NAME.toString(),
+ Person.Field.THUMBNAIL_URL.toString());
+
+ public SocialRequestContext(RequestContext request) {
+ super(request);
+ }
+
+ //these parameter handling methods are from social/dataservice/RequestItem.java
+ public int getStartIndex() {
+ String startIndex = request.getParameter(START_INDEX);
+ return startIndex == null ? DEFAULT_START_INDEX : Integer.valueOf(startIndex);
+ }
+
+ public int getCount() {
+ String count = request.getParameter(COUNT);
+ return count == null ? DEFAULT_COUNT : Integer.valueOf(count);
+ }
+
+ public PersonService.SortOrder getOrderBy() {
+ String orderBy = request.getParameter(ORDER_BY);
+ return orderBy == null
+ ? PersonService.SortOrder.topFriends
+ : PersonService.SortOrder.valueOf(orderBy);
+ }
+
+ public PersonService.FilterType getFilterBy() {
+ String filterBy = request.getParameter(FILTER_BY);
+ return filterBy == null
+ ? PersonService.FilterType.all
+ : PersonService.FilterType.valueOf(filterBy);
+ }
+
+ public Set<String> getFields() {
+ String paramValue = request.getParameter(FIELDS);
+ return paramValue == null
+ ? DEFAULT_PERSON_FIELDS
+ : Sets.newHashSet(paramValue.split(","));
+ }
+
+}
Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRouteManager.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRouteManager.java?rev=674954&r1=674953&r2=674954&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRouteManager.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialRouteManager.java Tue Jul 8 14:00:54 2008
@@ -17,70 +17,206 @@
*/
package org.apache.shindig.social.abdera;
+import org.apache.shindig.social.abdera.atom.ActivityAdapter;
+import org.apache.shindig.social.abdera.atom.DataAdapter;
+import org.apache.shindig.social.abdera.atom.PersonAdapter;
+import org.apache.shindig.social.abdera.json.PersonJsonAdapter;
+import org.apache.shindig.social.abdera.util.ValidRequestFilter;
+import org.apache.shindig.social.abdera.util.ValidRequestFilter.Format;
+
+import org.apache.abdera.i18n.templates.Route;
+import org.apache.abdera.protocol.Request;
import org.apache.abdera.protocol.server.CollectionAdapter;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.Target;
import org.apache.abdera.protocol.server.TargetType;
+import org.apache.abdera.protocol.server.impl.DefaultWorkspaceManager;
import org.apache.abdera.protocol.server.impl.RouteManager;
+import java.util.HashMap;
+import java.util.Map;
+
public class SocialRouteManager extends RouteManager {
- private PersonAdapter personAdapter;
- private DataAdapter dataAdapter;
- private ActivityAdapter activityAdapter;
+ private final PersonJsonAdapter personJsonAdapter;
+ private final PersonAdapter personAtomAdapter;
+ private final DataAdapter dataAtomAdapter;
+ private final ActivityAdapter activityAtomAdapter;
private static final String BASE = "/social/rest/";
- protected String base;
+ protected final String base;
- public SocialRouteManager(PersonAdapter personAdapter, DataAdapter dataAdapter,
- ActivityAdapter activityAdapter) {
+ public SocialRouteManager(PersonJsonAdapter personJsonAdapter, PersonAdapter personAtomAdapter,
+ DataAdapter dataAtomAdapter, ActivityAdapter activityAtomAdapter) {
this.base = BASE;
- this.personAdapter = personAdapter;
- this.dataAdapter = dataAdapter;
- this.activityAdapter = activityAdapter;
+ this.personJsonAdapter = personJsonAdapter;
+ this.personAtomAdapter = personAtomAdapter;
+ this.dataAtomAdapter = dataAtomAdapter;
+ this.activityAtomAdapter = activityAtomAdapter;
}
public void setRoutes() {
// People
- this.addRoute(RequestUrlTemplate.PROFILES_OF_CONNECTIONS_OF_USER,
- TargetType.TYPE_COLLECTION, personAdapter)
- .addRoute(RequestUrlTemplate.PROFILES_OF_FRIENDS_OF_USER,
- TargetType.TYPE_COLLECTION, personAdapter)
- .addRoute(RequestUrlTemplate.PROFILES_IN_GROUP_OF_USER,
- TargetType.TYPE_COLLECTION, personAdapter)
- .addRoute(RequestUrlTemplate.PROFILE_OF_CONNECTION_OF_USER,
- TargetType.TYPE_ENTRY, personAdapter)
- .addRoute(RequestUrlTemplate.PROFILE_OF_USER,
- TargetType.TYPE_ENTRY, personAdapter)
+ this.addRoute(RequestUrlTemplate.JSON_PROFILES_OF_CONNECTIONS_OF_USER,
+ TargetType.TYPE_COLLECTION, personJsonAdapter)
+ .addRoute(RequestUrlTemplate.ATOM_PROFILES_OF_CONNECTIONS_OF_USER,
+ TargetType.TYPE_COLLECTION, personAtomAdapter)
+ .addRoute(RequestUrlTemplate.JSON_PROFILES_OF_FRIENDS_OF_USER,
+ TargetType.TYPE_COLLECTION, personJsonAdapter)
+ .addRoute(RequestUrlTemplate.ATOM_PROFILES_OF_FRIENDS_OF_USER,
+ TargetType.TYPE_COLLECTION, personAtomAdapter)
+ .addRoute(RequestUrlTemplate.JSON_PROFILES_IN_GROUP_OF_USER,
+ TargetType.TYPE_COLLECTION, personJsonAdapter)
+ .addRoute(RequestUrlTemplate.ATOM_PROFILES_IN_GROUP_OF_USER,
+ TargetType.TYPE_COLLECTION, personAtomAdapter)
+ .addRoute(RequestUrlTemplate.JSON_PROFILE_OF_CONNECTION_OF_USER,
+ TargetType.TYPE_ENTRY, personJsonAdapter)
+ .addRoute(RequestUrlTemplate.ATOM_PROFILE_OF_CONNECTION_OF_USER,
+ TargetType.TYPE_ENTRY, personAtomAdapter)
+ .addRoute(RequestUrlTemplate.JSON_PROFILE_OF_USER,
+ TargetType.TYPE_ENTRY, personJsonAdapter)
+ .addRoute(RequestUrlTemplate.ATOM_PROFILE_OF_USER,
+ TargetType.TYPE_ENTRY, personAtomAdapter)
// Activities
.addRoute(RequestUrlTemplate.ACTIVITIES_OF_USER,
- TargetType.TYPE_COLLECTION, activityAdapter)
+ TargetType.TYPE_COLLECTION, activityAtomAdapter)
.addRoute(RequestUrlTemplate.ACTIVITIES_OF_FRIENDS_OF_USER,
- TargetType.TYPE_COLLECTION, activityAdapter)
+ TargetType.TYPE_COLLECTION, activityAtomAdapter)
.addRoute(RequestUrlTemplate.ACTIVITIES_OF_GROUP_OF_USER,
TargetType.TYPE_COLLECTION, null)
.addRoute(RequestUrlTemplate.ACTIVITY_OF_USER,
- TargetType.TYPE_ENTRY, activityAdapter)
+ TargetType.TYPE_ENTRY, activityAtomAdapter)
// AppData
.addRoute(RequestUrlTemplate.APPDATA_OF_APP_OF_USER,
- TargetType.TYPE_COLLECTION, dataAdapter)
+ TargetType.TYPE_COLLECTION, dataAtomAdapter)
.addRoute(RequestUrlTemplate.APPDATA_OF_FRIENDS_OF_USER,
- TargetType.TYPE_COLLECTION, dataAdapter)
+ TargetType.TYPE_COLLECTION, dataAtomAdapter)
;
}
/**
- * This extension of the addRoute from the parent allows a RequestUrlTemplate
- * to be passed in instead of a name and pattern. This is just a convenience
- * method to clean up the code. The parent method maps routes to types and
- * adapters.
- *
+ * Adds an additional addRoute constructor that allows a RequestUrlTemplate to be passed in
+ * instead of a name and pattern. This is just a convenience method to clean up the code.
+ *
* @param template RequestUrlTemplate enum should contain names and patterns.
* @param type TargetType
* @param collectionAdapter CollectionAdapter
* @return addRoute from the parent RouteManager
*/
- public SocialRouteManager addRoute(RequestUrlTemplate template,
- TargetType type, CollectionAdapter collectionAdapter) {
- return (SocialRouteManager) addRoute(template.toString(),
- base + template.getRoutePattern(), type, collectionAdapter);
+ public SocialRouteManager addRoute(RequestUrlTemplate template, TargetType type,
+ CollectionAdapter collectionAdapter) {
+ return addRoute(template.name(), base + template.getRoutePattern(), type, template
+ .getFormatRestriction(), collectionAdapter);
+ }
+
+ /**
+ * Adds an additional addRoute constructor beyond abdera.protocol.server.impl.RouteManager#resolve
+ * so that a requirement can be added to each Route that includes the format that the Route
+ * accepts
+ *
+ * @param name The name of the Route
+ * @param pattern The pattern to match and generate urls for requests
+ * @param type The TargetType for the Route
+ * @param format A Format enum of ATOM or JSON
+ * @param collectionAdapter The CollectionAdapter to associate with the Route
+ */
+ public SocialRouteManager addRoute(
+ String name,
+ String pattern,
+ TargetType type,
+ ValidRequestFilter.Format format,
+ CollectionAdapter collectionAdapter) {
+ Map<String, String> requirements = new HashMap<String, String>();
+ if (format !=null){
+ requirements.put(ValidRequestFilter.FORMAT_FIELD, format.toString());
+ }
+ Route route = new Route(name, pattern, null, requirements);
+ route2CA.put(route, collectionAdapter);
+ return (SocialRouteManager) addRoute(route, type);
+ }
+
+ /**
+ * Overrides abdera.protocol.server.impl.RouteManager#resolve to add a format restriction for
+ * routes
+ */
+ public Target resolve(Request request) {
+ RequestContext context = (RequestContext) request;
+ String uri = context.getTargetPath();
+ int idx = uri.indexOf('?');
+ if (idx != -1) {
+ uri = uri.substring(0, idx);
+ }
+
+ for(RouteTargetType routeTarget : targets) {
+ // check if the formatRestriction requirement is in the route and if it is satisfied.
+ if (matchRequestFormat(context, routeTarget.getRoute())) {
+ // match the path portion of the url
+ if (routeTarget.getRoute().match(uri)) {
+ CollectionAdapter ca = route2CA.get(routeTarget.getRoute());
+ if (ca != null) {
+ context.setAttribute(DefaultWorkspaceManager.COLLECTION_ADAPTER_ATTRIBUTE, ca);
+ }
+ return getTarget(context, routeTarget.getRoute(), uri, routeTarget.getTargetType());
+ }
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * The ValidRequestFilter runs after the initial resolving of the target so it cannot ensure that
+ * a request will be stopped if the url does not have a proper format parameter. This method
+ * returns false if there is no valid format parameter.
+ *
+ * However, if the format requirement field in the route is null, we call it a match, since that
+ * means the route does not have a format restriction
+ *
+ * @param request Abdera's RequestContext
+ * @param route Abdera's Route object
+ */
+ private boolean matchRequestFormat(RequestContext request, Route route) {
+ Format requestFormat = ValidRequestFilter.getFormatTypeFromRequest(request);
+ String routeFormatRestriction = route.getRequirement(ValidRequestFilter.FORMAT_FIELD);
+ if (requestFormat == null) {
+ return false;
+ } else {
+ if (routeFormatRestriction != null) {
+ return routeFormatRestriction.toUpperCase().equals(
+ requestFormat.getDisplayValue().toUpperCase());
+ }
+ return true;
+ }
+ }
+
+ private Target getTarget(
+ RequestContext context,
+ Route route,
+ String uri,
+ TargetType type) {
+ return new RouteTarget(type, context, route, uri);
+ }
+
+ // TODO: We should probably move the static methods here into a helper class
+ public static RequestUrlTemplate getUrlTemplate(RequestContext request) {
+ String routeName = getRoute(request).getName();
+ return RequestUrlTemplate.valueOf(routeName);
+ }
+
+ /**
+ * This assumes the target resolver was a RouteManager and returns a Route
+ * object. If it does not, it throws a NPE for now. It could also deal with a
+ * Regex resolver
+ *
+ * @param request Abdera's RequestContext
+ * @return The Route object that matched the request.
+ */
+ public static Route getRoute(RequestContext request) {
+ Object matcher = request.getTarget().getMatcher();
+ if (matcher instanceof Route) {
+ return (Route) matcher;
+ } else {
+ throw new NullPointerException();
+ }
}
}
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/AbstractSocialEntityCollectionAdapter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/AbstractSocialEntityCollectionAdapter.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/AbstractSocialEntityCollectionAdapter.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/AbstractSocialEntityCollectionAdapter.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,389 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.shindig.social.abdera.atom;
+
+import org.apache.shindig.common.BasicSecurityToken;
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.common.SecurityTokenDecoder;
+import org.apache.shindig.common.SecurityTokenException;
+import org.apache.shindig.common.crypto.BlobCrypterException;
+import org.apache.shindig.social.abdera.RequestUrlTemplate;
+import org.apache.shindig.social.abdera.util.ValidRequestFilter;
+import org.apache.shindig.social.abdera.util.ValidRequestFilter.Format;
+import org.apache.shindig.social.opensocial.PeopleService;
+import org.apache.shindig.social.opensocial.model.IdSpec;
+import org.apache.shindig.social.opensocial.util.BeanJsonConverter;
+import org.apache.shindig.social.opensocial.util.BeanXmlConverter;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import org.apache.abdera.Abdera;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.i18n.templates.Route;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.model.Person;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.ResponseContext;
+import org.apache.abdera.protocol.server.context.ResponseContextException;
+import org.apache.abdera.protocol.server.impl.AbstractEntityCollectionAdapter;
+import org.json.JSONException;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * By extending this class it becomes easy to build Collections which are backed
+ * by a set of Social entities - such as a person or activity.
+ *
+ * This base class also has the data connection to the People service and some
+ * helper methods for getting social graph information.
+ *
+ * @param <T> The entity that this is backed by.
+ */
+
+public abstract class AbstractSocialEntityCollectionAdapter<T> extends
+ AbstractEntityCollectionAdapter<T> {
+ private static final Logger logger = Logger
+ .getLogger(AbstractEntityCollectionAdapter.class.getName());
+
+ // the name of the URI query parameter that is the gadget security token
+ protected static final String SECURITY_TOKEN_PARAM = "st";
+
+ protected PeopleService peopleService;
+ protected final String ID_PREFIX;
+ protected final Factory factory;
+ private BeanXmlConverter beanXmlConverter;
+ private BeanJsonConverter beanJsonConverter;
+ protected SecurityTokenDecoder securityTokenDecoder;
+
+ public AbstractSocialEntityCollectionAdapter() {
+ ID_PREFIX = "urn:guid:";
+ factory = new Abdera().getFactory();
+ }
+
+ /**
+ * All the adapters need access to the PeopleService, which has the basic
+ * social graph information. Each service adapter will also add an instance
+ * of their respective data service.
+ * TODO: Also include groups service in base?
+ * @param peopleService The people service
+ */
+ @Inject
+ public void setPeopleService(PeopleService peopleService) {
+ this.peopleService = peopleService;
+ }
+
+ @Inject
+ public void setConverters(BeanXmlConverter beanXmlConverter,
+ BeanJsonConverter beanJsonConverter) {
+ this.beanXmlConverter = beanXmlConverter;
+ this.beanJsonConverter = beanJsonConverter;
+ }
+
+ @Inject
+ public void setSecurityTokenDecoder(SecurityTokenDecoder
+ securityTokenDecoder) {
+ this.securityTokenDecoder = securityTokenDecoder;
+ }
+
+ /**
+ * Get the token from the "st" url parameter or throw an exception.
+ * @param request Abdera's RequestContext
+ * @return SecurityToken
+ * @throws SecurityTokenException If the token is invalid
+ */
+ /**
+ * Reads the gadget security token out of an {@link HttpServletRequest},
+ * making sure to return null if there are problems.
+ */
+ protected SecurityToken getSecurityToken(RequestContext request) {
+ String token = request.getParameter(SECURITY_TOKEN_PARAM);
+
+ if (token == null || token.trim().length() == 0) {
+ return null;
+ }
+
+ try {
+ Map<String, String> params =
+ Collections.singletonMap(SecurityTokenDecoder.SECURITY_TOKEN_NAME,
+ token);
+ return securityTokenDecoder.createToken(params);
+ } catch (SecurityTokenException e) {
+ String message = new StringBuilder()
+ .append("found security token, but couldn't decode it ")
+ .append("(treating it as not present). token is: ")
+ .append(token)
+ .toString();
+ logger.warning(message);
+ return null;
+ }
+ }
+
+ /**
+ * This alternate version of getSecurityToken adds the ability to generate a
+ * new security token based on some viewerid supplied.
+ *
+ * @param request Abdera's RequestContext
+ * @param viewerId The viewer ID to fake.
+ * @return A call to the parent getSecurityToken which returns a SecurityToken
+ */
+ protected SecurityToken getSecurityToken(RequestContext request,
+ final String viewerId) {
+ SecurityToken token = getSecurityToken(request);
+
+ if (token == null) {
+ try {
+ return new BasicSecurityToken("o", viewerId, "a", "d", "u", "m");
+ } catch (BlobCrypterException be) {
+ be.printStackTrace();
+ return null;
+ }
+ }
+ return token;
+ }
+
+ /**
+ * @param request RequestContext
+ * @param resourceRouteVariable The route variable for the entry. So, for a
+ * route pattern of /:collection/:id, with "id" resourceRouteVariable this
+ * would remove "id" in the generated URL.
+ * @return The absolute request URI (includes server name, port, etc) URL for
+ * the collection of the entry.
+ */
+ public String getFeedIriForEntry(RequestContext request,
+ String resourceRouteVariable) {
+ Map<String, Object> params = Maps.newHashMap();
+ Route theRoute = getRoute(request);
+ for (String var: theRoute.getVariables()){
+ Object value = request.getTarget().getParameter(var);
+ if (!params.containsKey(var) && !var.equals(resourceRouteVariable)) {
+ params.put(var, value);
+ }
+ }
+ String uri = request.urlFor(theRoute.getName(), params);
+ return request.getResolvedUri().resolve(uri).toString();
+ }
+
+ /**
+ * This assumes the target resolver was a RouteManager and returns a Route
+ * object. If it does not, it throws a NPE for now. It could also deal with a
+ * Regex resolver
+ *
+ * @param request Abdera's RequestContext
+ * @return The Route object that matched the request.
+ */
+ public static Route getRoute(RequestContext request) {
+ Object matcher = request.getTarget().getMatcher();
+ if (matcher instanceof Route) {
+ return (Route) matcher;
+ } else {
+ throw new NullPointerException();
+ }
+ }
+
+ // TODO: We should probably move the static methods here into a helper class
+ public static RequestUrlTemplate getUrlTemplate(RequestContext request) {
+ String routeName = getRoute(request).getName();
+ return RequestUrlTemplate.valueOf(routeName);
+ }
+
+ @Override
+ public Object getContent(T entity, RequestContext request)
+ throws ResponseContextException {
+ Format format = ValidRequestFilter.getFormatTypeFromRequest(request);
+ Content content = factory.newContent();
+
+ switch (format) {
+ case ATOM:
+ content.setContentType(Content.Type.XML);
+ content.setValue(beanXmlConverter.convertToXml(entity));
+ break;
+ case JSON:
+ content.setContentType(Content.Type.TEXT);
+ content.setValue(beanJsonConverter.convertToJson(entity).toString());
+ break;
+ }
+ return content;
+ }
+
+ public abstract String getSummary(T entity) throws ResponseContextException;
+
+ /**
+ * Add the details to an entry.
+ *
+ * @param request Abdera's RequestContext.
+ * @param entry The entry FOM object.
+ * @param feedIri The feed IRI that the entry came from.
+ * @param entity The object that the entry is based on.
+ */
+ @Override
+ protected String addEntryDetails(RequestContext request, Entry entry,
+ IRI feedIri, T entity) throws ResponseContextException {
+ addRequiredEntryDetails(request, entry, feedIri, entity);
+ addOptionalEntryDetails(request, entry, feedIri, entity);
+ return getLink(entity, feedIri, request);
+ }
+
+ /**
+ * This very similar to the superclass's addEntryDetails but modified to do a
+ * minimum of required fields.
+ *
+ * @param request Abdera's RequestContext.
+ * @param entry The entry FOM object.
+ * @param feedIri The feed IRI that the entry came from.
+ * @param entity The object that the entry is based on.
+ * @throws ResponseContextException If the authors can not be fetched
+ */
+ protected void addRequiredEntryDetails(RequestContext request, Entry entry,
+ IRI feedIri, T entity) throws ResponseContextException {
+ entry.setId(getId(entity));
+ entry.setTitle(getTitle(entity));
+ entry.setUpdated(getUpdated(entity));
+ entry.setSummary(getSummary(entity));
+ List<Person> authors = getAuthors(entity, request);
+ if (authors != null) {
+ for (Person a : authors) {
+ entry.addAuthor(a);
+ }
+ }
+ }
+
+ /**
+ * This is a good place for the subclass to do any special processing of the
+ * entry element to customize it beyond the basic atom fields like title and
+ * author.
+ *
+ * @param request Abdera's RequestContext.
+ * @param entry The entry FOM object.
+ * @param feedIri The feed IRI that the entry came from.
+ * @param entity The object that the entry is based on.
+ * @throws ResponseContextException If some entry data can not be fetched
+ */
+ protected void addOptionalEntryDetails(RequestContext request, Entry entry,
+ IRI feedIri, T entity) throws ResponseContextException {
+ }
+
+ /**
+ * Create the base feed for the requested collection.
+ *
+ * TODO: This method needs to be refactored to deal with hoisting and json.
+ *
+ * @param request Abdera's RequestContext
+ */
+ @Override
+ protected Feed createFeedBase(RequestContext request)
+ throws ResponseContextException {
+ Factory factory = request.getAbdera().getFactory();
+ Feed feed = factory.newFeed();
+ String link = getHref(request);
+ // TODO: this should create links that are aware of the request format.
+ feed.addLink(link, "self", "application/atom+xml", null, null, 0);
+ feed.setId(getId(request));
+ feed.setTitle(getTitle(request));
+ feed.addAuthor(getAuthor(request));
+ feed.setUpdated(new Date());
+ return feed;
+ }
+
+ protected void addEditLinkToEntry(Entry entry) throws Exception {
+ if (getEditUriFromEntry(entry) == null) {
+ entry.addLink(entry.getId().toString(), "edit");
+ }
+ }
+
+ protected String getEditUriFromEntry(Entry entry) throws Exception {
+ String editUri = null;
+ List<Link> editLinks = entry.getLinks("edit");
+ if (editLinks != null) {
+ for (Link link : editLinks) {
+ // if there is more than one edit link, we should not automatically
+ // assume that it's always going to point to an Atom document
+ // representation.
+ if (link.getMimeType() != null) {
+ if (link.getMimeType().match("application/atom+xml")) {
+ editUri = link.getResolvedHref().toString();
+ break;
+ }
+ } else {
+ // edit link with no type attribute is the right one to use
+ editUri = link.getResolvedHref().toString();
+ break;
+ }
+ }
+ }
+ return editUri;
+ }
+
+ /**
+ * Unimplemented HTTP methods
+ */
+
+ @Override
+ public ResponseContext deleteEntry(RequestContext request) {
+ return null;
+ }
+
+ @Override
+ public ResponseContext putEntry(RequestContext request) {
+ return null;
+ }
+
+ /**
+ * Gets the IDs of friends for the given user.
+ *
+ * @param request Abdera's RequestContext
+ * @param uid The User ID to get friends for.
+ * @return A list of ID strings.
+ */
+ public List<String> getFriendIds(RequestContext request, String uid) {
+ SecurityToken token = getSecurityToken(request, uid);
+ IdSpec idSpec = new IdSpec(null, IdSpec.Type.VIEWER_FRIENDS);
+ try {
+ return peopleService.getIds(idSpec, token);
+ } catch (JSONException e) {
+ // TODO: Ignoring this for now. Eventually we can make the service apis
+ // fit the restful model better. For now, it is worth some hackiness to
+ // keep the interfaces stable.
+ return null;
+ }
+ }
+
+ /**
+ * Gets the IDs of connections of the given user.
+ *
+ * @param request Abdera's RequestContext
+ * @param uid The User ID to get connections for.
+ * @return A list of ID strings.
+ */
+ public List<String> getConnectionIds(RequestContext request, String uid,
+ SecurityTokenDecoder securityTokenDecoder, PeopleService peopleService) {
+ // TODO: Implement connections. For now, just return friends
+ return getFriendIds(request, uid);
+ }
+
+
+}
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/ActivityAdapter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/ActivityAdapter.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/ActivityAdapter.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/ActivityAdapter.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.shindig.social.abdera.atom;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.abdera.RequestUrlTemplate;
+import org.apache.shindig.social.abdera.SocialRouteManager;
+import org.apache.shindig.social.opensocial.ActivitiesService;
+import org.apache.shindig.social.opensocial.model.Activity;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Person;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.context.ResponseContextException;
+
+import org.apache.commons.betwixt.io.BeanReader;
+import org.xml.sax.SAXException;
+
+import java.beans.IntrospectionException;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * This Collection is backed by a set of Activity entities
+ */
+public class ActivityAdapter extends
+ AbstractSocialEntityCollectionAdapter<Activity> {
+
+ private final ActivitiesService activitiesService;
+
+ /**
+ * The Adapter needs Activities, People and Groups.
+ * The PeopleService comes from the base class. Groups is unimplemented.
+ * @param activitiesService The activities service
+ */
+ @Inject
+ public ActivityAdapter(ActivitiesService activitiesService) {
+ this.activitiesService = activitiesService;
+ }
+
+ /**
+ * Query the underlying model for an Activity object.
+ *
+ * @param request RequestContext
+ * @return An Activity entity.
+ */
+ @Override
+ public Activity getEntry(String resourceName, RequestContext request)
+ throws ResponseContextException {
+ String aid = resourceName;
+ String uid = request.getTarget().getParameter("uid");
+ SecurityToken authToken = getSecurityToken(request, uid);
+ return activitiesService.getActivity(uid, aid, authToken).getResponse();
+ }
+
+ /**
+ * atom:entry/atom:id aliases the "id" field. In the Atom format, it is
+ * translated into the required URI data type by prepending "urn:guid:" to the
+ * OpenSocial ID string.
+ */
+ @Override
+ public String getId(Activity activityObj) throws ResponseContextException {
+ return ID_PREFIX + activityObj.getId();
+ }
+
+ // hoisting rule: atom:entry/atom:author/atom:uri aliases "user_id"
+ @Override
+ public List<Person> getAuthors(Activity activityObj, RequestContext request)
+ throws ResponseContextException {
+ Person author = factory.newAuthor();
+ author.setUri(ID_PREFIX + activityObj.getUserId());
+ return Arrays.asList(author);
+ }
+
+ /**
+ * Get the name of the entry resource (used to construct links)
+ */
+ @Override
+ public String getName(Activity activityObj) throws ResponseContextException {
+ return activityObj.getId();
+ }
+
+ // hoisting rule: atom:entry/atom:title aliases "title"
+ @Override
+ public String getTitle(Activity activityObj) throws ResponseContextException {
+ return activityObj.getTitle();
+ }
+
+ // hoisting rule: atom:entry/atom:updated aliases POSTED_TIME for Activity
+ // or the generation time if no better information is available.
+ @Override
+ public Date getUpdated(Activity activityObj) throws ResponseContextException {
+ return activityObj.getUpdated();
+ }
+
+ // hoisting rule: atom:entry/atom:summary aliases "body"
+ @Override
+ public String getSummary(Activity activityObj)
+ throws ResponseContextException {
+ return activityObj.getBody();
+ }
+
+ // hoisting rule: atom:entry/atom:published aliases POSTED_TIME
+ public Long getPublished(Activity activityObj)
+ throws ResponseContextException {
+ // TODO: Add published element to the entry object.
+ // TODO: Switch based on output format from RFC date to epoch-based.
+ // POSTED_TIME is seconds since the epoch.
+ return activityObj.getPostedTime();
+ }
+
+ /**
+ * This is where some activity entry format customization happens.
+ *
+ * @param request Abdera's RequestContext.
+ * @param entry The entry FOM object.
+ * @param feedIri The feed IRI that the entry came from.
+ * @param activityObj The object that the entry is based on.
+ * @throws ResponseContextException
+ */
+ @Override
+ protected void addOptionalEntryDetails(RequestContext request, Entry entry,
+ IRI feedIri, Activity activityObj) throws ResponseContextException {
+ String link = getLink(activityObj, feedIri, request);
+ // TODO: this should create links that are aware of the request format.
+ entry.addLink(link, "self", "application/atom+xml", null, null, 0);
+
+ // TODO:
+ // atom:entry/atom:generator/atom:uri aliases "app_id"
+ // atom:entry/atom:published aliases POSTED_TIME
+ }
+
+ /**
+ * Unimplemented Data methods
+ */
+ @Override
+ public void deleteEntry(String resourceName, RequestContext request)
+ throws ResponseContextException {
+ // TODO: Auto-generated method stub
+ }
+
+ /**
+ * Query the underlying model for the list activity objects.
+ *
+ * There is some logic to handle some request dispatching here since this
+ * adapter handles the getFeed method for three Activity collections:
+ * ACTIVITIES_OF_USER, ACTIVITIES_OF_FRIENDS_OF_USER and
+ * ACTIVITIES_OF_GROUP_OF_USER
+ *
+ * @param request RequestContext
+ * @return A List Activity entities.
+ */
+ @Override
+ public Iterable<Activity> getEntries(RequestContext request)
+ throws ResponseContextException {
+ String uid = request.getTarget().getParameter("uid");
+ List<String> ids = Lists.newArrayList();
+ switch (SocialRouteManager.getUrlTemplate(request)) {
+ case ACTIVITIES_OF_USER :
+ ids.add(uid);
+ break;
+ case ACTIVITIES_OF_FRIENDS_OF_USER :
+ // TODO: Change activities service to handle the friend lookup itself
+ ids = getFriendIds(request, uid);
+ break;
+ case ACTIVITIES_OF_GROUP_OF_USER :
+ // TODO: add something like ids = getGroupIds(request, gid);
+ String gid = request.getTarget().getParameter("gid");
+ break;
+ default:
+ // TODO: Clean this code up so we don't need this check
+ throw new UnsupportedOperationException(
+ "The activity adpater was reached with an unsupported url");
+ }
+
+ SecurityToken authToken = getSecurityToken(request, uid);
+ return activitiesService.getActivities(ids, authToken).getResponse();
+ }
+
+ /**
+ * When an entry is POSTed to a collection, purpose is to add that entry
+ * to the collection.
+ *
+ * Currently, the following method only handles POST to the following
+ * collection
+ * /activities/:uid/@self
+ */
+ @Override
+ public Activity postEntry(String title, IRI id, String summary, Date updated,
+ List<Person> authors, Content content, RequestContext request)
+ throws ResponseContextException {
+
+ // handle Atom/XML. TODO handle Json
+
+ /*
+ * To extract Activity obj from the posted Entry, content element is
+ * used. To make this work, content element should contain everything
+ * we need to create the Activity object correctly. If there are
+ * some fields in other atom: elements, copy them into the content element.
+ * i.e., implement "reverse hoisting" logic here
+ */
+ // TODO is userId field in content element (correspodns to Activity.userId)
+ // supposed to be filled in by the caller
+ // OR is it to be picked up from the ":uid" param on URL
+ // assuming that it is already filled by the caller.
+
+ String contentXml = content.getValue();
+ BeanReader reader = new BeanReader();
+ Activity postedActivity = null;
+ try {
+ reader.registerBeanClass("activity", Activity.class);
+ StringReader rd = new StringReader(contentXml);
+ postedActivity = (Activity)reader.parse(rd);
+ } catch (IntrospectionException e) {
+ throw new ResponseContextException(null, e);
+ } catch (IOException e) {
+ throw new ResponseContextException(null, e);
+ } catch (SAXException e) {
+ throw new ResponseContextException(null, e);
+ }
+
+ /*
+ * in Atom/Xml, the posted entry is returned to the original caller
+ * with the following fields being "potentially" different from
+ * what the caller sent:
+ * 1. atom:id server can optionally assign a new id to the entry
+ * and return it to the caller. This may not be reqd
+ * 2. editUri link should be added to the entry if required.
+ * refer to atom spec on all you need to know about this field.
+ * included the following methods in baseclass to help with this
+ * . addEditLinkToEntry(Entry entry)
+ * . getEditUriFromEntry(Entry entry)
+ *
+ * TODO figure out WHERE the postedEntry doc is being constructed in
+ * Abdera. thats where the logic to add editUri should be included.
+ *
+ */
+
+ // add this to list of activities of the user
+ String uid = request.getTarget().getParameter("uid");
+ SecurityToken authToken = getSecurityToken(request, uid);
+
+ // the following modifies postedActivity - which is then returned to
+ // the caller.
+ // TODO the following method should be modified (or new method needed)
+ // to return the postedActivity
+ activitiesService.createActivity(uid, postedActivity, authToken);
+ return postedActivity;
+ }
+
+ @Override
+ public void putEntry(Activity entry, String title, Date updated,
+ List<Person> authors, String summary, Content content,
+ RequestContext request) throws ResponseContextException {
+ // TODO: Implement
+ }
+
+ /**
+ * Collection-level hoisting rules
+ */
+
+ /**
+ * The collection-level URL. Calls the getFeedIriForEntry and nulls "aid".
+ *
+ * @param request RequestContext
+ * @return The absolute request URI (includes server name, port, etc) URL
+ */
+ @Override
+ public String getHref(RequestContext request) {
+ return getFeedIriForEntry(request, "aid");
+ }
+
+ @Override
+ public String getId(RequestContext request) {
+ // TODO: what really to return for the feed ID? Better data will help.
+ return getHref(request);
+ }
+
+ // hoisting rule: atom:entry/atom:source/atom:link@rel="self" aliases
+ // "stream_url"
+ // TODO: "stream_url"
+
+ // hoisting rule: atom:entry/atom:source/atom:title aliases "stream_title"
+ // TODO: stream_title can't be accessed right here....
+ public String getTitle(RequestContext request) {
+ String routename = SocialRouteManager.getRoute(request).getName();
+ return RequestUrlTemplate.valueOf(routename).getDescription();
+ }
+
+ // hoisting rule: atom:entry/atom:author/atom:uri aliases "user_id"
+ @Override
+ public String getAuthor(RequestContext request)
+ throws ResponseContextException {
+ return request.getTarget().getParameter("uid");
+ }
+
+
+}
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/DataAdapter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/DataAdapter.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/DataAdapter.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/DataAdapter.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,167 @@
+package org.apache.shindig.social.abdera.atom;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+
+import org.apache.shindig.social.abdera.RequestUrlTemplate;
+import org.apache.shindig.social.abdera.SocialRouteManager;
+import org.apache.shindig.social.opensocial.DataService;
+import org.apache.shindig.social.opensocial.model.DataCollection;
+import org.apache.shindig.social.opensocial.model.DataCollection.Data;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.context.ResponseContextException;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * This adapter translates abdera requests into calls to the DataService.
+ * It both fetches and updates Data.
+ * TODO: I'm not sure all of this hoisting is right.
+ */
+public class DataAdapter extends AbstractSocialEntityCollectionAdapter<Data> {
+ private static Logger logger = Logger
+ .getLogger(DataAdapter.class.getName());
+
+ private final DataService dataService;
+
+ @Inject
+ public DataAdapter(DataService dataService) {
+ this.dataService = dataService;
+ }
+
+ @Override
+ public Data getEntry(String resourceName,
+ RequestContext request) throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getId(Data entry) throws ResponseContextException {
+ return entry.getPersonId();
+ }
+
+ @Override
+ public String getName(Data entry)
+ throws ResponseContextException {
+ return entry.getPersonId();
+ }
+
+ @Override
+ public String getTitle(Data entry)
+ throws ResponseContextException {
+ return entry.getPersonId();
+ }
+
+ @Override
+ public Date getUpdated(Data entry)
+ throws ResponseContextException {
+ return new Date();
+ }
+
+ @Override
+ public String getSummary(Data entry)
+ throws ResponseContextException {
+ return entry.getPersonId();
+ }
+
+ /**
+ * Query the underlying model for the list of data objects.
+ *
+ * There is some logic to handle some request dispatching here since this
+ * adapter handles the getFeed method for three Data collections:
+ * APPDATA_OF_APP_OF_USER, APPDATA_OF_FRIENDS_OF_USER
+ *
+ * @param request RequestContext
+ * @return A List Person entities.
+ */
+ @Override
+ public DataCollection getEntries(RequestContext request)
+ throws ResponseContextException {
+ String uid = request.getTarget().getParameter("uid");
+ List<String> ids = Lists.newArrayList();
+ switch (SocialRouteManager.getUrlTemplate(request)) {
+ case APPDATA_OF_APP_OF_USER :
+ ids.add(uid);
+ break;
+ case APPDATA_OF_FRIENDS_OF_USER :
+ ids = getFriendIds(request, uid);
+ break;
+ default:
+ throw new UnsupportedOperationException(
+ "The person adpater was reached with an unsupported url");
+ }
+ return new DataCollection(dataService.getPersonData(ids, getKeys(request),
+ getSecurityToken(request, uid)).getResponse());
+ }
+
+ private List<String> getKeys(RequestContext request) {
+ String fields = request.getTarget().getParameter("fields");
+ if (fields == null) {
+ return Lists.newArrayList();
+ }
+ String[] keyArray = fields.split(",");
+ return Arrays.asList(keyArray);
+ }
+
+ @Override
+ public Data postEntry(String title, IRI id,
+ String summary, Date updated,
+ List<org.apache.abdera.model.Person> authors, Content content,
+ RequestContext request) throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putEntry(Data data,
+ String title, Date updated, List<org.apache.abdera.model.Person> authors,
+ String summary, Content content, RequestContext request)
+ throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void deleteEntry(String resourceName, RequestContext request)
+ throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Collection-level hoisting rules
+ */
+
+ /**
+ * The collection-level URL. Calls the getFeedIriForEntry and nulls "pid".
+ *
+ * @param request RequestContext
+ * @return The absolute request URI (includes server name, port, etc) URL
+ */
+ @Override
+ public String getHref(RequestContext request) {
+ return getFeedIriForEntry(request, "pid");
+ }
+
+ @Override
+ public String getId(RequestContext request) {
+ // TODO: what really to return for the feed ID? Better data will help.
+ return getHref(request);
+ }
+
+ public String getTitle(RequestContext request) {
+ String routename = SocialRouteManager.getRoute(request).getName();
+ return RequestUrlTemplate.valueOf(routename).getDescription();
+ }
+
+ // hoisting rule: atom:entry/atom:author/atom:uri aliases ?
+ @Override
+ public String getAuthor(RequestContext request)
+ throws ResponseContextException {
+ return request.getTarget().getParameter("uid");
+ }
+
+}
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/PersonAdapter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/PersonAdapter.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/PersonAdapter.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/atom/PersonAdapter.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.shindig.social.abdera.atom;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.abdera.RequestUrlTemplate;
+import org.apache.shindig.social.abdera.SocialRouteManager;
+import org.apache.shindig.social.opensocial.PeopleService;
+import org.apache.shindig.social.opensocial.model.Person;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.context.ResponseContextException;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * This Collection is backed by a set of Person entities
+ * The Adapter needs People and Groups.
+ * The PeopleService comes from the base class. Groups is unimplemented.
+ */
+public class PersonAdapter extends
+ AbstractSocialEntityCollectionAdapter<Person> {
+ private static Logger logger = Logger
+ .getLogger(PersonAdapter.class.getName());
+
+
+ /**
+ * Query the underlying model for an Person object.
+ *
+ * @param resourceName An id string that identifies a Person.
+ * @param request Abdera's RequestContext.
+ * @return An Person entity.
+ */
+ @Override
+ public Person getEntry(String resourceName, RequestContext request)
+ throws ResponseContextException {
+ String uid = request.getTarget().getParameter("uid");
+ // Get a token assuming the {uid} is the viewerid.
+ // TODO: Replace hardcoded token viewerid with a SubjectResolver.
+ SecurityToken authToken = getSecurityToken(request, uid);
+ return peopleService.getPerson(resourceName, authToken).getResponse();
+ }
+
+ /**
+ * Get's the name of the specific resource requested.
+ * There is some logic to handle some request parsing here since this
+ * adapter handles the getEntry method for two Person entries:
+ * PROFILE_OF_CONNECTION_OF_USER and PROFILE_OF_USER
+ */
+ @Override
+ protected String getResourceName(RequestContext request) {
+ switch (SocialRouteManager.getUrlTemplate(request)) {
+ case ATOM_PROFILE_OF_CONNECTION_OF_USER:
+ List<String> cids = getConnectionIds(request, request.getTarget()
+ .getParameter("uid"), securityTokenDecoder, peopleService);
+ // TODO: Improve the service apis so we can get rid of relational code.
+ for (String cid : cids) {
+ if (cid.equals(request.getTarget().getParameter("pid"))) {
+ return cid;
+ }
+ }
+ return null;
+ case ATOM_PROFILE_OF_USER:
+ return request.getTarget().getParameter("uid");
+ default:
+ // TODO: Clean this code up so we don't need this check
+ throw new UnsupportedOperationException(
+ "The person adpater was reached with an unsupported url");
+ }
+ }
+
+ /**
+ * atom:entry/atom:id aliases the "id" field. In the Atom format, it is
+ * translated into the required URI data type by prepending "urn:guid:" to the
+ * OpenSocial ID string.
+ */
+ @Override
+ public String getId(Person personObj) throws ResponseContextException {
+ return ID_PREFIX + personObj.getId();
+ }
+
+ // hoisting rule: atom:entry/atom:author/atom:uri aliases ?
+ @Override
+ public List<org.apache.abdera.model.Person> getAuthors(Person personObj,
+ RequestContext request) throws ResponseContextException {
+ org.apache.abdera.model.Person author = factory.newAuthor();
+ author.setUri(ID_PREFIX + personObj.getId());
+ return Arrays.asList(author);
+ }
+
+ /**
+ * Get the name of the entry resource (used to construct links)
+ */
+ @Override
+ public String getName(Person personObj) throws ResponseContextException {
+ return personObj.getId();
+ }
+
+ // hoisting rule: atom:entry/atom:title aliases ?
+ @Override
+ public String getTitle(Person personObj) throws ResponseContextException {
+ return personObj.getName().getUnstructured();
+ }
+
+ @Override
+ public Date getUpdated(Person personObj) throws ResponseContextException {
+ return personObj.getUpdated();
+ }
+
+ // hoisting rule: atom:entry/atom:summary aliases ?
+ @Override
+ public String getSummary(Person personObj) throws ResponseContextException {
+ return null;
+ }
+
+ // hoisting rule: atom:entry/atom:published aliases ?
+ public Long getPublished(Person personObj)
+ throws ResponseContextException {
+ // TODO: Add published element to the entry object.
+ // TODO: Switch based on output format from RFC date to epoch-based.
+ // POSTED_TIME is seconds since the epoch.
+ return null;
+ }
+
+ /**
+ * This is where some person entry format customization happens.
+ *
+ * @param request Abdera's RequestContext.
+ * @param entry The entry FOM object.
+ * @param feedIri The feed IRI that the entry came from.
+ * @param personObj The object that the entry is based on.
+ * @throws ResponseContextException
+ */
+ @Override
+ protected void addOptionalEntryDetails(RequestContext request, Entry entry,
+ IRI feedIri, Person personObj) throws ResponseContextException {
+ String link = getLink(personObj, feedIri, request);
+ // TODO: this should create links that are aware of the request format.
+ entry.addLink(link, "self", "application/atom+xml", null, null, 0);
+
+ // TODO:
+ // atom:entry/atom:published aliases ?
+ }
+
+ /**
+ * Unimplemented Data methods
+ */
+ @Override
+ public void deleteEntry(String resourceName, RequestContext request)
+ throws ResponseContextException {
+ // TODO: Auto-generated method stub
+ }
+
+ /**
+ * Query the underlying model for the list person objects.
+ *
+ * There is some logic to handle some request dispatching here since this
+ * adapter handles the getFeed method for three Person collections:
+ * PROFILES_OF_CONNECTIONS_OF_USER, PROFILES_OF_FRIENDS_OF_USER and
+ * PROFILES_IN_GROUP_OF_USER
+ *
+ * @param request RequestContext
+ * @return A List Person entities.
+ */
+ @Override
+ public Iterable<Person> getEntries(RequestContext request)
+ throws ResponseContextException {
+ String uid = request.getTarget().getParameter("uid");
+ List<String> ids;
+ switch (SocialRouteManager.getUrlTemplate(request)) {
+ case ATOM_PROFILES_OF_CONNECTIONS_OF_USER :
+ ids = getConnectionIds(request, uid, securityTokenDecoder, peopleService);
+ break;
+ case ATOM_PROFILES_OF_FRIENDS_OF_USER :
+ // TODO: Change activities service to handle the friend lookup itself
+ ids = getFriendIds(request, uid);
+ break;
+ case ATOM_PROFILES_IN_GROUP_OF_USER :
+ // TODO: add something like ids = getGroupIds(request, gid);
+ // For now, this just returns the friends.
+ ids = getFriendIds(request, uid);
+ break;
+ default:
+ // TODO: Clean this code up so we don't need this check
+ throw new UnsupportedOperationException(
+ "The person adpater was reached with an unsupported url");
+ }
+ // Get a token assuming the {uid} is the viewerid.
+ // TODO: Replace hardcoded token viewerid with a SubjectResolver.
+ SecurityToken authToken = getSecurityToken(request, uid);
+ return peopleService.getPeople(ids, PeopleService.SortOrder.name, null, 0,
+ 100, null, authToken).getResponse().getItems();
+ }
+
+ @Override
+ public Person postEntry(String title, IRI id, String summary, Date updated,
+ List<org.apache.abdera.model.Person> authors, Content content,
+ RequestContext request) throws ResponseContextException {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public void putEntry(Person personObj, String title, Date updated,
+ List<org.apache.abdera.model.Person> authors, String summary,
+ Content content, RequestContext request) throws ResponseContextException {
+ // TODO: Implement
+ }
+
+ /**
+ * Collection-level hoisting rules
+ */
+
+ /**
+ * The collection-level URL. Calls the getFeedIriForEntry and nulls "pid".
+ *
+ * @param request RequestContext
+ * @return The absolute request URI (includes server name, port, etc) URL
+ */
+ @Override
+ public String getHref(RequestContext request) {
+ return getFeedIriForEntry(request, "pid");
+ }
+
+ @Override
+ public String getId(RequestContext request) {
+ // TODO: what really to return for the feed ID? Better data will help.
+ return getHref(request);
+ }
+
+ public String getTitle(RequestContext request) {
+ String routename = SocialRouteManager.getRoute(request).getName();
+ return RequestUrlTemplate.valueOf(routename).getDescription();
+ }
+
+ // hoisting rule: atom:entry/atom:author/atom:uri aliases ?
+ @Override
+ public String getAuthor(RequestContext request)
+ throws ResponseContextException {
+ return request.getTarget().getParameter("uid");
+ }
+
+}
Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/JSONFilter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/JSONFilter.java?rev=674954&r1=674953&r2=674954&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/JSONFilter.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/JSONFilter.java Tue Jul 8 14:00:54 2008
@@ -17,8 +17,9 @@
*/
package org.apache.shindig.social.abdera.json;
-import org.apache.shindig.social.abdera.AbstractSocialEntityCollectionAdapter;
+import org.apache.shindig.social.abdera.RawResponseContext;
import org.apache.shindig.social.abdera.RequestUrlTemplate;
+import org.apache.shindig.social.abdera.SocialRouteManager;
import org.apache.shindig.social.abdera.util.ValidRequestFilter;
import org.apache.shindig.social.abdera.util.ValidRequestFilter.Format;
@@ -56,6 +57,10 @@
public ResponseContext filter(RequestContext request, FilterChain chain) {
ResponseContext resp = chain.next(request);
+ // Bypass the filter for RawResponseContext responses.
+ if (resp.getClass().equals(RawResponseContext.class)){
+ return resp;
+ }
Format format = ValidRequestFilter.getFormatTypeFromRequest(request);
if (format == Format.ATOM) {
return resp;
@@ -126,7 +131,7 @@
JSONObject json = new JSONObject();
try {
- RequestUrlTemplate url = AbstractSocialEntityCollectionAdapter
+ RequestUrlTemplate url = SocialRouteManager
.getUrlTemplate(request);
// If the type of object is Data, then we want to create a JSONObject
Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/PersonJsonAdapter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/PersonJsonAdapter.java?rev=674954&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/PersonJsonAdapter.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/json/PersonJsonAdapter.java Tue Jul 8 14:00:54 2008
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.shindig.social.abdera.json;
+
+import com.google.inject.Inject;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.abdera.SocialRequestContext;
+import org.apache.shindig.social.abdera.SocialRouteManager;
+import org.apache.shindig.social.dataservice.GroupId;
+import org.apache.shindig.social.dataservice.RestfulCollection;
+import org.apache.shindig.social.dataservice.UserId;
+import org.apache.shindig.social.opensocial.model.Person;
+import org.apache.shindig.social.opensocial.util.BeanJsonConverter;
+
+import java.util.concurrent.Future;
+
+public class PersonJsonAdapter extends SimpleJsonAdapter<Person> {
+
+ @Inject
+ public PersonJsonAdapter(BeanJsonConverter beanJsonConverter) {
+ super(beanJsonConverter);
+ }
+
+ @Override
+ public Future<ResponseItem<Person>> getEntity(SocialRequestContext request, SecurityToken token) {
+ String uid = request.getTarget().getParameter("uid");
+ UserId userId = UserId.fromJson(uid);
+
+ return personService.getPerson(userId, request.getFields(), token);
+ }
+
+ @Override
+ public Future<ResponseItem<RestfulCollection<Person>>> getEntities(SocialRequestContext request,
+ SecurityToken token) {
+ String uid = request.getTarget().getParameter("uid");
+ UserId userId = UserId.fromJson(uid);
+
+ GroupId groupId;
+ switch (SocialRouteManager.getUrlTemplate(request)) {
+ case JSON_PROFILES_OF_CONNECTIONS_OF_USER:
+ groupId = new GroupId(GroupId.Type.all, "all");
+ break;
+ case JSON_PROFILES_OF_FRIENDS_OF_USER:
+ // TODO: Change activities service to handle the friend lookup itself
+ groupId = new GroupId(GroupId.Type.friends, "friends");
+ break;
+ case JSON_PROFILES_IN_GROUP_OF_USER:
+ groupId = new GroupId(GroupId.Type.groupId, request.getTarget().getParameter("gid"));
+ break;
+ default:
+ // TODO: Clean this code up so we don't need this check
+ throw new UnsupportedOperationException(
+ "The person adpater was reached with an unsupported url");
+ }
+
+ return personService.getPeople(userId, groupId, request.getOrderBy(), request.getFilterBy(),
+ request.getStartIndex(), request.getCount(), request.getFields(), token);
+ }
+}