TumblrJ

Practice makes perfect

I’ve finally brought down the TumblrJ service class to it’s easiest use. The cool thing with this design is that for 99% of use cases, you can use the defaults, and for those times when you’re in a bind or need finer grained control over the construction of the objects, you can do that as well. Here it is:

Read all:

TumblrService service = new TumblrService("myblogname");
TumbleLog log = service.read();

Read with a filter:

TumblrReadOptions readOptions = new TumblrReadOptions();
readOptions.setType(TumblrType.REGULAR);

TumblrService service = new TumblrService("myblogname");
TumbleLog log = service.read(readOptions);

Well, you get the idea. Basically, no more configuration of the TumblrHttpReader, TumblrHttpOptions and TumblrJProperties. No nonsense defaults are used and hidden inside the TumblrService class.

Using TumblrJ to write posts, read credentials and running the unit tests

Some more progress with the api. This post will be about writing a post using the API, then reading a users credential information and I’ll finish off with the specifics on running the unit tests.

All code examples will focus on using the code through Spring, but this can all be done without Spring very easily (i.e.: Instead of building your instances through DI, just build them in the code yourself).

Writing

Same as with reading Tumblr information, you’ll need to:

  1. Setup an instance of the TumblrService class
  2. That class in turn needs a properly configured ITumblrReader instance. Since there’s only one implementation of that interfae, you’ll use TumblrHttpReader
  3. That in turns needs a TumblrConnectionOptions object with at the very minimum the name of your Tumblr log.

The small difference with here is that the write() method needs to be given a Credentials object to work.

Therefore, the Spring configuration would look something like:

<beans>
    <bean id="tumblrJProperties" class="org.mikem.tumblr.api.util.TumblrJProperties"/>

    <bean id="connectionOptions" class="org.mikem.tumblr.api.http.TumblrConnectionOptions">
        <property name="name" value="${logname}"/>
    </bean>

    <bean id="reader" class="org.mikem.tumblr.api.http.TumblrHttpReader">
        <property name="tumblrConnectionOptions" ref="connectionOptions"/>
        <property name="properties" ref="tumblrJProperties"/>
    </bean>

    <bean id="credentials" class="org.mikem.tumblr.api.util.Credentials">
        <property name="email" value="${email}"/>
        <property name="password" value="${password}"/>
    </bean>

    <bean id="service" class="org.mikem.tumblr.api.TumblrService">
        <property name="reader" ref="reader"/>
    </bean>
</beans>

In the above configuration, you’ll need to replace the ${} variables with your own values.

A test case to go with this configuration would then look something like:

@Test
public void testWrite() throws Exception {
    ApplicationContext context = new ClassPathXmlApplicationContext("test-spring-context.xml");
    TumblrService service = (TumblrService) context.getBean("service");
    Credentials credentials = (Credentials) context.getBean("credentials");

    RegularPost post = new RegularPost();
    post.setBody("Test post");
    post.setPrivatePost(true);
    post.setTitle("Test post title");

    TumblePost savedPost = service.write(post, credentials);

    Assert.assertNotNull(savedPost);
    Assert.assertNotNull(savedPost.getId());
}

Simple enough! Notice that for now, only RegularPost has been tested.

Reading credentials

The Tumblr api offers a way to pull out all the relevant information for a user. To get that information, and using the same Spring configuration outlined above, you’d do something like:

@Test
public void testReadAuthenticationInformaiton() {
    ApplicationContext context = new ClassPathXmlApplicationContext("test-spring-context.xml");
    TumblrService service = (TumblrService) context.getBean("service");
    Credentials credentials = (Credentials) context.getBean("credentials");

    User user = service.getUserInformation(credentials);
    Assert.assertNotNull(user);
    Assert.assertTrue(user.getUserTumblelogs().size() > 0);
}

Check out the User object to see the wealth of information returned by Tumblr.

Running the tests

The unit tests found in the source code are tightly coupled to Tumblr itself, and by extension a users log, email and password. Therefore, so that everyone may run the tests on their own log and with their own credentials, all tests are devised to be configured against a file called private-test-config.properties. That file should be found on the classpath.

The contents is straightforward enough:

logname=mylogname
email=myemail
password=mypassword

If you look at the @Before method of the BaseServiceTest class, you’ll notice the call to that file. Again, if the file isn’t present on the classpath, the tests will fail miserably. I haven’t checked that file in for obvious reasons!

Using TumblrJ to read

With the current implementation of TumblrJ working properly for straight reads of different types, I figured I’d show a quick demo of the api usage (without Spring – I’ll post something about that later).

The api revolves around a single class called TumblrService. The class pretty much acts like a facade hiding the implementation details. The TumblrService needs a couple things to work properly:

  1. A TumblrJProperties instance
  2. An implementation of the ITumblrReader interface. The api includes the only one possible at this point which is an HTTP specific implementation.

Configuration

The TumblrJProperties class automatically initializes itself by looking for a file called tumblrj-config.properties in the classpath. You can override the name by using the 1 arg constructor. For now, the file needs to be found in the classpath.

The file contains basic information about paths, url’s, … The contents should look something exactly like:

base.url=http://{0}.tumblr.com
path.read=/api/read
path.authenticate=/api/authenticate
path.delete=/api/delete

Since most of these properties are pretty much standard, I’ll implement a defaults mechanism so that they aren’t mandatory.

Connection options

The other object needed to use the TumblrService and TumblrHttpReader classes is a TumblrConnectionOptions instance. At a very minimum, you’ll need to enter the name of your tumblr log (usualy, the first part in your tumblr.com url). If you want to access private posts, you’ll want to put in your email and password.

And for those who want fine grained control over the connection options, the object can also accept a org.apache.commons.httpclient.params.HttpClientParams instance which will be used on every http call.

Full Example

TumblrConnectionOptions connectionOptions = new TumblrConnectionOptions();
connectionOptions.setName("lama");

TumblrHttpReader reader = new TumblrHttpReader();

TumblrJProperties properties = new TumblrJProperties();
reader.setProperties(properties);
reader.setTumblrConnectionOptions(connectionOptions);

TumblrService service = new TumblrService();
service.setReader(reader);
TumblrReadOptions readOptions = new TumblrReadOptions();
readOptions.setStart(1);
readOptions.setNum(1);

TumbleLog log = service.read(readOptions);

Explanation

Lines 1 through 11 were pretty much explaines. Lines 12, 13 and 14 are interesting in that they let you configure the read options by letting you filter the data. The available options include:

  • Wether or not to include private posts
  • The start and number of posts to return (for paging and limiting results)
  • The id of the post
  • The type of post

Check out the TumblrReadOptions class for details.

Line 13 is the line where the read is executed and a TumbleLog object returned. That object will include a List of TumblePost objects as well as a gamut of other information concerning the returned results. As mentionned before, the test package contains a lot of usefull unit tests showing off how to use the different read options.