Shindig Spring Example
Example Overview
MockPersonSpi
MockPersonSpi is a mock implementation of PersonService, returning mock responses to the getPerson and getPeople methods. Obviously, in a real world scenario this should be a real implementation of PersonService, but the mock serves our purposes well for this example.
Code Block |
---|
public class MockPersonSpi implements PersonService { private static final UserId JOHN = new UserId(UserId.Type.userId, "john.doe"); private static final UserId JANE = new UserId(UserId.Type.userId, "jane.doe"); private static final UserId[] FRIENDS = {JOHN, JANE}; public Future<Person> getPerson(UserId userId, Set<String> fields, SecurityToken token) throws SocialSpiException { Person person = new PersonImpl(); person.setId(userId.getUserId()); return ImmediateFuture.newInstance(person); } public Future<RestfulCollection<Person>> getPeople(Set<UserId> userIds, GroupId groupId, CollectionOptions collectionOptions, Set<String> fields, SecurityToken token) throws SocialSpiException { try { List<Person> people = new ArrayList<Person>(); switch (groupId.getType()) { case self: for (UserId userId: userIds) { Person person = new PersonImpl(); person.setId(userId.getUserId()); people.add(person); } break; case friends: for (UserId userId: FRIENDS) { Person person = new PersonImpl(); person.setId(userId.getUserId()); people.add(person); } break; case all: throw new SocialSpiException(ResponseError.NOT_IMPLEMENTED, "Not yet implemented",null); case groupId: throw new SocialSpiException(ResponseError.NOT_IMPLEMENTED, "Not yet implemented",null); case deleted: throw new SocialSpiException(ResponseError.NOT_IMPLEMENTED, "Not yet implemented",null); default: throw new SocialSpiException(ResponseError.BAD_REQUEST, "Group ID not recognized",null); } return ImmediateFuture.newInstance(new RestfulCollection<Person>(people, 0, people.size())); } catch (Exception e) { throw new SocialSpiException(ResponseError.INTERNAL_ERROR, "Exception occurred", e); } } } |
GuiceModule
GuiceModule is the Guice configuration module that binds any custom shindig bindings, and in this scenario the only customization needed is to bind MockPersonSpi to the PersonService interface. To bind an instance of MockPersonSpi, GuiceModule will use ApplicationContextFactory to get Spring's ApplicationContext, and in turn use ApplicationContext to get the MockPersonSpi bean instance. Since GuiceModule extends SocialApiGuiceModule, it calls super.configure() so that the default social bindings are therefore also configured.
Code Block |
---|
public class GuiceModule extends SocialApiGuiceModule { private static final String PERSON_SPI_BEAN_NAME = "personSpi"; @Override protected void configure() { ApplicationContext applicationContext = ApplicationContextFactory.getApplicationContext(); this.bind(PersonService.class).toInstance((PersonService) applicationContext.getBean(PERSON_SPI_BEAN_NAME)); super.configure(); } } |
ApplicationContextFactory
ApplicationContextFactory acts as a holder to Spring's ApplicationContext, thus providing a static getter method to the context.
Code Block |
---|
public class ApplicationContextFactory { private static final String[] LOCATIONS = {"application-context.xml"}; private static final AbstractApplicationContext CONTEXT = new ClassPathXmlApplicationContext(LOCATIONS); private ApplicationContextFactory() {} public static AbstractApplicationContext getApplicationContext() { return CONTEXT; } } |
application-context.xml
The application-context.xml Spring configuration file is where Spring beans are defined, and in this instance a bean definition has been included for MockPersonSpi.
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="personSpi" class="org.apache.shindig.samples.springexample.spi.MockPersonSpi"/> </beans> |
web.xml
To have this example running within a servlet container it's necessary to add GuiceModule into the web.xml file.
Code Block |
---|
<?xml version="1.0"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_4.dtd"> <web-app> <display-name>shindig-spring-example web descriptor</display-name> <!-- configuration --> <!-- If you have your own Guice module(s), put them here as a colon-separated list. --> <context-param> <param-name>guice-modules</param-name> <param-value> org.apache.shindig.common.PropertiesModule: org.apache.shindig.samples.springexample.config.GuiceModule </param-value> </context-param> <!-- Shindig authentication filter --> <filter> <filter-name>authFilter</filter-name> <filter-class>org.apache.shindig.auth.AuthenticationServletFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/social/*</url-pattern> </filter-mapping> <!-- GuiceServletContextListener --> <listener> <listener-class>org.apache.shindig.common.servlet.GuiceServletContextListener</listener-class> </listener> <!-- ApplicationServletContextListener --> <!-- Destroys Spring's ApplicationContext at shutdown, forcing bean defined destroy-methods to be invoked --> <listener> <listener-class>org.apache.shindig.samples.springexample.servlet.ApplicationServletContextListener</listener-class> </listener> <!-- Serve REST api --> <servlet> <servlet-name>restapiServlet</servlet-name> <servlet-class> org.apache.shindig.protocol.DataServiceServlet </servlet-class> </servlet> <!-- Serve RPC api --> <servlet> <servlet-name>jsonRpcServlet</servlet-name> <servlet-class> org.apache.shindig.protocol.JsonRpcServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>restapiServlet</servlet-name> <url-pattern>/social/rest/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jsonRpcServlet</servlet-name> <url-pattern>/social/rpc/*</url-pattern> </servlet-mapping> </web-app> |
Example Source Code
- Check-out from svn (https://svn.apache.org/repos/asf/shindig/sandbox/trunk/shindig-spring-example/) and look at the README to get started.