Jinx Updated

Jinx, a Java library to access the Flickr API, has been updated. The latest version supports these API entry points:
* activity
* auth
* blogs
* collections
* commons
* contacts
* favorites
* galleries
* groups
* groups.members
* photos
* photosets

You can get it on github.

Happy coding!

Knicker Version 2 and Examples

Version 2 of Knicker, the Java library for the Wordnik API, is now available. This version supports version 4 of the Wordnik API.

In addition to supporting version 4 of the Wordnik API, this version of Knicker follows the organization of the API more closely. Previously, all the methods were in one class, Knicker.java. Knicker.java still exists, but it is now abstract and contains only constants used by other classes. The methods that access the Wordnik API are now in classes named after the section of the API they access. So account API methods are now in AccountApi, word API methods are in WordApi, and so on. This makes the source a little more manageable, and allows a more modular approach to testing and development.

This version also includes JUnit tests for all the Wordnik API methods. During the development of version 2, these tests helped find several bugs in the API, which the Wordnik team quickly fixed.

One of the coolest features of the new Wordnik API is the ability to retrieve audio pronunciation data for words. Retrieval of the audio data is fully supported in Knicker version 2. Playback of the data is left up to you.

In addition to a new version of the library, I have also started a Knicker Examples project. There is currently one example that shows how to retrieve and display text definitions, and retrieve and play the audio definition for the word. The project contains all necessary libraries, so you can grab it and go. I will probably be adding additional examples as I have time, and contributions are welcome.

As always, please let me know when you find bugs. You can contact me via email, leave a comment here, or post to the Wordnik developers mailing list, which I am subscribed to.

Happy coding!

Knicker, a Wordnik API Library for Java

Wordnik is an online dictionary that bills itself as “The most comprehensive dictionary in the known universe”. Recently I wanted to add the ability to lookup word definitions to one of my applications, so I wrote a Java library to wrap the Wordnik API. The library is called Knicker, and is available under the terms of the GPL.

Using Knicker is simple:

  1. Sign up for a Wordnik API key
  2. Set the system property WORDNIK_API_KEY to your API key
  3. Put the Knicker library in your classpath
  4. Call methods on the library

Here’s an example of how to use the API to get a list of definitions for the word “siren”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.List;
import net.jeremybrooks.knicker.Knicker;
import net.jeremybrooks.knicker.dto.Definition;
import net.jeremybrooks.knicker.dto.TokenStatus;

public class TestKnicker {


    public static void main(String[] args) throws Exception {
        // use your API key here
        System.setProperty("WORDNIK_API_KEY", "");

   
    // check the status of the API key
    TokenStatus status = Knicker.status();
    if (status.isValid()) {
        System.out.println("API key is valid.");
    } else {
        System.out.println("API key is invalid!");
        System.exit(1);
    }

   
    // get a list of definitions for a word
    List<Definition> def = Knicker.definitions("siren");
    System.out.println("Found " + def.size() + " definitions.");

    int i = 1;
    for (Definition d : def) {
        System.out.println((i++) + ") " + d.getPartOfSpeech() + ": " + d.getText());
    }

    }
}

For more information about the Wordnik API, see their developers page.

Introducing Jinx

Jinx is a Java library that provides access to the Flickr API. It is pure Java, with no external dependencies.

The package structure is straightforward. Each Flickr API section (activity, auth, blogs, etc) has a corresponding class in the net.jeremybrooks.jinx.api package. The API classes are named ActivityApi, AuthApi, BlogsApi, etc. Each API class is implemented as a singleton. You can obtain an instance of an API class with a call to getInstance():

1
BlogsApi bApi = BlogsApi.getInstance();

Each Flickr method has a corresponding method in the API class. So if you want to call the Flickr flickr.blogs.getList method, you will call the getList() method on BlogsApi:

1
BlogsApi.getInstance().getList();

The API methods that return data will generally return instances of the Data Transfer Objects located in the net.jeremybrooks.jinx.dto package. The DTO’s are very simple classes, containing getter and setter methods and no other logic. All DTO’s implement java.io.Serializable.

Flickr returns a status message along with data for every API call. Jinx will check that status message for you. If Flickr reports an error, an instance of net.jeremybrooks.jinx.JinxException will be thrown. The Flickr error code and error message can be retrieved by calling getErrorCode and getErrorMessage.

This project is currently being used in SuprSetr. Currently, the following Flickr API sections are implemented:

  • Activity
  • Auth
  • Blogs
  • Collections
  • Commons
  • Photos
  • Photosets

Other sections of the Flickr API will be implemented over time. If you want to use Jinx now, you can get the source code from github and build it with ant. If you just want the binary jar file, you can download it at the Jinx home page. Javadocs are located here.

The test directory contains sample code showing how to use Jinx to access the Flickr API. Here is the TestAuthorization class, showing how to authorize an application to use Flickr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.io.File;
import net.jeremybrooks.jinx.Jinx;
import net.jeremybrooks.jinx.JinxConstants;
import net.jeremybrooks.jinx.api.AuthApi;
import net.jeremybrooks.jinx.dto.Frob;
import net.jeremybrooks.jinx.dto.Token;

/**
 * This test class demonstrates how to perform authorization for your application.
 *
 * Your application must have its own key and secret. These can be obtained here:
 * http://www.flickr.com/services/apps/create/apply/?
 *
 *
 * @author jeremyb
 */

public class TestAuthorizaion {

    /*
     * Get a key for your app here:
     * http://www.flickr.com/services/apps/create/apply/?
     */

    private static final String KEY = "";
    private static final String SECRET = "";

    public static void main(String[] args) {

    File tokenFile = new File("/tmp/myToken");
    Token token = null;

    try {
        // Attempt to initialize with an existing token
        if (tokenFile.exists()) {
        token = new Token();
        token.load(tokenFile);
        Jinx.getInstance().init(KEY, SECRET, token);

        } else {

        // No token exists, so initialize with our key and secret,
        // then prompt user to authorize our application
        Jinx.getInstance().init(KEY, SECRET);
        Frob frob = AuthApi.getInstance().getFrob(JinxConstants.PERMS_READ);

        // Send user to the login URL
        // In a real application, you would probably do this in a GUI
        // of some sort
        System.out.println("Please go to this URL and allow access: " + frob.getLoginUrl());
        System.out.println("After you have authorized this application, press a key.");

        // Wait for user to press a key
        System.in.read();

        // Complete authorization by getting the token and telling
        // Jinx about it
        token = AuthApi.getInstance().getToken(frob);
        Jinx.getInstance().setToken(token);

        System.out.println("Authorization successful.");

        // The token can be stored for future use, and is valid until
        // the user revokes access
        token.store(new File("/tmp/myToken"));
        }
    } catch (Exception e) {
        System.out.println("Oops, something went wrong!");
        e.printStackTrace();
    }
    }
}

Jinx is released under the Gnu General Public License.

Commenting Is Not An Option

Commenting code is a part of development and engineering that is overlooked all too often. It might be that developers are simply under so much pressure that they feel there is no time for commenting. It might be viewed as a hassle. And, it is not something that is required for the code to compile and execute.

The compiler sees comments as optional, but that does not mean that developers should see them the same way.

Commenting is a vital, I would even go as far as to say critical, part of any software engineering effort. If you have been in the business for any length of time, you have undoubtedly come across code that is missing meaningful comments. You probably spent a significant amount of time trying to figure out not only what the code was doing, but what the original author was intending to do. Perhaps you have even experienced this with your own code!

Try to get in the habit of adding meaningful comments while you are coding, and do not consider the project finished until the comments are in place. Often, the comments in code are the most up-to-date documentation that a project will have. Requirements and technical specs may be out of date once the coding actually starts, and keeping documentation up to date which is separate from the code is a much more complex task than keeping comments up to date. If you use Java, take a look at the article How to Write Doc Comments for the Javadoc Tool. Look at the Java source and see how the comments are formatted. With a little practice, commenting will become second nature.

What if you do not use Java? That’s ok — every language has some way to leave comments, and the principles apply just the same.

Here are five ways to make commenting work for you:

1) Comment the method signature before you write any code inside the method. Then write the code implementing the described behavior.

2) Comment private methods and fields, not just public ones. You can then tell the javadoc tool to include private classes in the generated documentation. The resulting javadocs will be invaluable for anybody that needs to maintain the program in the future. You can easily generate two sets of documents if needed, one for public use and one for private, internal use.

3) Update comments when you modify the code. Comments that do not match what the code is doing are not helpful.

4) Take advantage of version control keyword expansion in your comments. For example, including the CVS keyword $Id$ in your comment will tell you who checked in the file last, the date, the RCS filename, and the revision number.

5) Let your IDE do the work. Modern IDE’s understand javadoc comment format, and can often generate the boilerplate of the comment for you, including @param, @return, and @throws tags. You just have to fill in the blanks.

What other ways do you make comments in code work for you? Feel free to leave a comment below, and tell us about it!

Java Network Proxies

Have you ever spent hours lovingly coding your Next Great Program, only to discover that part of your audience cannot use it because they are behind a proxy server? If you are going to be using the network, it pays to plan ahead for this situation. Adding proxy capability to your program is not very difficult. Here’s a quick code snippet that does just that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void enableProxy(String host, int port, final String username, final char[] password) {
    System.setProperty("http.proxyHost", host);
    System.setProperty("http.proxyPort", String.valueOf(port));

    if (username != null && !username.isEmpty()) {
        Authenticator.setDefault(new Authenticator() {

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }

        });
    }
}

Calling this method with a host and port will set up the system properties necessary for proxy access to work. If the username is not null, it will also set up a PasswordAuthentication object to perform authentication as needed. To disable the proxy, call this method:

1
2
3
4
public static void clearProxy() {
    System.clearProperty("http.proxyHost");
    System.clearProperty("http.proxyPort");
}

Now, all you have to do is provide a way for the user to enter the proxy settings, persist the settings, and call the enableProxy method. At application startup, you can read the settings from where you have stored them and enable the proxy.

Another option is to tell the JVM to use your system proxy settings. However, I have had problems with this detecting the system properties in some cases on some operating systems:

1
System.setProperty("java.net.useSystemProxies", "true");

Adding proxy support to your code is easy! Taking the time to add proxy support to your application will save you headaches later on down the road. Happy coding!

Blocking User Input In A Swing GUI

When developing a desktop application, there are times when you want to prevent the user from interacting with the GUI. For example, you may be doing work in the background, and want to make sure you finish before allowing the user to continue. Perhaps the most obvious way to do this is to disable each component in the GUI. This works, but is not a very elegant or maintainable solution. The appearance of each GUI component changes when disabled, and if you add a new component to the window in the future, you will have to remember to disable it as well.

Fortunantly, Swing provides a better way to do this: The glass pane. The glass pane is one of the layers of a JRootPane. It is transparent and normally not visible. However, if you set it as visible, you can effectively block all user interaction with the contents of the window.

Carrying this one step further, it is possible to set the glass pane to be a panel of your own design. By doing this, you can effectively overlay anything you want on top of the current window, including messages to the user, animated progress icons, etc. The screen shot below shows the BlockerPanel in action. The icon and text are on the glass pane, which intercepts all user interaction with the window.

BlockerPanel Demo

The code to implement a BlockerPanel is straightforward, and the resulting class is easy to use. You can download my BlockerPanel class along with a simple demonstration program and use it in any of your projects. The source code is released with no restrictions, so feel free to improve upon it. There are many useful features that could be added, and there are parts of the code that could be improved. I’ll leave this as an exercise for the reader.

BlockerDemo source code and test program.

Further reading:

How to use Root Panes on sun.com