Using Wildcard Expressions in Java
Getting a File from a Web Site or FTP Site
Java FTP Class
Java Server Addin for Domino
HttpEcho Program
Java HTTP Proxy
Java MessageBoxes, InputBoxes, and ProgressBars
XML NodeReader Class
Java Sample Code Database
Transform WSDL Servlet
Undocumented Base64 Java Classes
Using Java Reflection to Get Class Information
Multi-Part MIME Message Parser
Java RichTextOutputStream Class
Accessing the System Clipboard with Java
Searching for Text in Files
Manipulating JPEG Images
Testing ReplaceSubstring Routines
Terminating Threads and Reacting to Shutdown in Java
Open JAR Files Natively In Windows
Using Wildcard Expressions in Java
August 31, 2002 (updated September 11, 2002)
Here's a Java class that I wrote to evaluate basic wildcard expressions (using *, ?, or []) in Java strings. If you're using the JDK/J2SE 1.4 or higher, you should probably use the java.util.regex package to make Regular Expressions to provide string pattern-matching functionality, because it will give you a much greater range of functionality. There are (at the time of this writing) some good examples of Regular Expression usage here on the Sun website. However, sometimes we Notes developers are stuck using older versions of the JDK...
I also included a sample class called "jdir.java" that calls the PatternMatch class and uses it in a FilenameFilter, as an example. It simulates the very basic functionality of the "dir" command in DOS (make sure you enclose those wildcard arguments in quotes!).
My good friend Mark (a fantastic Java programmer) also told me about an open source regular expression library at apache.org that will work with JDK versions prior to 1.4. That one should be much more full-featured than the one I wrote. Thanks Mark!
Getting a File from a Web Site or FTP Site
August 31, 2002
This is a Java class I wrote to get a file (or a web page) from a web site or an anonymous ftp site. It has additional functionality to allow you to do this kind of thing through a proxy server, which makes it a little more useful in an office setting.
Java FTP Class
August 31, 2002 (updated September 11, 2002)
This information has been expanded and moved to a separate page:
see JavaFtp.htm
Java Server Addin for Domino
October 14, 2002 (updated May 17, 2003)
Here's an example of how to write an R5 Domino Server Addin using Java (which is normally something you'd do in C or C++). I got the idea from this tip on the SearchDomino site. The example I wrote doesn't do much, but it should give you a good framework for writing your own Addins. I tried to be as liberal as possible with my comments.
Keep in mind that using the the lotus.notes.addins.JavaServerAddin class from Notes.jar is totally unsupported functionality (at least in R5), so you are using it at your own risk. Normal caveats apply. This also means that I had to make some educated guesses about some of the functionality that I describe in the source code, so please send me a note if you find any mistakes.
JavaAddinTest.java
JavaAddinTest.class
HttpEcho Program
November 21, 2002
This is a simple Java program that takes incoming HTTP requests on a given port and returns them right back to the sender of the request. It's useful for looking at the HTTP headers sent by your browser, or seeing the structure of SOAP requests that are being sent to a server. For example, just compile the Java file into a class file and run "java HttpEcho 8080", and then point your browser to "http://localhost:8080/whatever" to see your browser headers.
Actually, I wrote two slightly different versions of the program: HttpEcho.java, which is single-threaded, and HttpEchoMT.java, which is multi-threaded. That's just to give you an example of how to do some simple multi-threading on a program like this.
Java HTTP Proxy
December 18, 2002 (updated February 1, 2003)
This is a multi-threaded HTTP proxy server implementation in Java. Ideally you'll just run it on your local workstation so you can watch HTTP requests going back and forth (because of the way the threading works in this code, I wouldn't recommend running it as a proxy server that serves multiple clients -- see the comments in the code for more detail).
You can either point this proxy to a direct network/Internet connection, or you can point it to another proxy server (if that's how you're set up). Even though the jProxy class has a 'main' method that allows you to run it all by itself, I also tried to structure the methods in the class so you can easily call it from other classes. I didn't spend the time to javadoc any of the comments, but the code should be commented well enough that you can understand what's going on by reading through it. (Updated on Feb 1 so that the HTTP header elements are separated by \r\n instead of just \n, to comply with the official HTTP spec).
Java MessageBoxes, InputBoxes, and ProgressBars
December 23, 2002 (updated January 15, 2002)
Here's a classic case of a simple little piece of functionality that ended up taking lines and lines of code to implement. All I wanted to do was add a MessageBox and an InputBox to a Java agent that would run in the Notes client, and I wanted to use the java.awt classes so I wouldn't have to package the javax.swing classes along with the agent (note that Swing was included with Lotus Notes starting with release 6, but I was stuck with R5 at the time). It wouldn't have been too bad, except for the fact that java.awt doesn't have a native way of displaying multiple lines of text in a Label-type component...
Since it wasn't quite as straightforward as I thought it would be, I packaged up some sample code, added comments to the source, and posted it for you here. It's a MessageBox class that allows you to present simple Ok/Cancel dialogs, input boxes, drop-down lists, and multiple selection lists. Also included as a special bonus is a MultiLineLabel class that you can use to create text labels of a fixed width that have multiple lines (with text wrapping, too!).
Of course, just because this is implemented as a Lotus Notes agent doesn't mean that you can't use it in your other Java applets/applications. If you do any kind of Java UI work without the Swing classes, this code will probably come in handy.
Update: Here's a similar piece of code that allows you to implement a non-modal Progress Bar in a Java agent. Like the MessageBox example above, the ProgressBar class uses only the java.awt classes, so you don't have to package anything special with your agents that use it.
XML NodeReader Class
January 17, 2003 (updated February 27, 2003)
The NodeReader class provides some basic functionality for stepping through the elements of a w3c XML Node, so you don't have to write your own loops around a NodeList. It's similar to the TreeWalker class that ships with many org.w3c.dom compatible packages, but the XML4j.jar package that ships with Lotus Notes/Domino doesn't have a TreeWalker class, so I wrote this.
This has been tested with the JDK 1.1.8 and 1.3.1, both in an R5 Notes agent and in a stand-alone Java application. It's also got JavaDoc comments, so you can produce some basic documentation (although I did include a code sample with the comments, so that should help you along).
Transform WSDL Servlet
February 19, 2003
I was playing around with WSDL files last week, and I ran across this article about transforming a WSDL file using XSLT. As I was reading it, I thought it would be interesting to write a servlet that would apply the XSL file in the article to any given WSDL file on the web. So I wrote one, and you can download it below.
It worked on my R5 Domino servers using the Domino Servlet Manager, and the method in the code that actually performs the XSL transformation could also be easily copied and pasted into a Notes agent (note that it may not work properly if your server is sitting behind a proxy server). If nothing else, this might be a good framework for how to write a simple servlet.
There's also some interesting information about transforming WSDL files using XSL on the CapeScience site.
Undocumented Base64 Java Classes
February 23, 2003
While I was poking around through my Java jar file, I discovered a couple of undocumented (i.e. not in the JavaDocs) classes in Sun's Java distribution called sun.misc.BASE64Encoder and sun.misc.BASE64Decoder. As expected, they Base64 encode and decode data, and they even have really convenient methods for encoding/decoding an InputStream to an OutputStream, which is handy for working with files (I used reflection to figure out what the public methods were).
As always, you should be a little cautious working with undocumented features, but I'd bet these are pretty safe (Base64 ain't rocket science). It could save you a little coding or the need to import extra classes into your project, and I even tested the functionality with an R5 Notes client, so I'd guess these classes have been around for a while (at least since the 1.1.8 JDK).
Here's some sample code that demonstrates example usage:
Using Java Reflection to Get Class Information
February 24, 2003
This is a simple example of how to use Java reflection to get information about a compiled Java class. This is useful for getting the public fields, constructors, and methods of a class that you may not have documentation for.
Multi-Part MIME Message Parser
March 4, 2003
This is a class that will read and parse an RFC 1521 multi-part MIME message. It works with any InputStream, it's been tested with the 1.1.8 and 1.3.1 JDK, and it doesn't require any additional classes or overhead.
The code is pretty well commented (JavaDoc comments and everything), including a class usage example, so you should be able to figure out how to use it fairly quickly.
Accessing the System Clipboard with Java
May 6, 2003
This is a wrapper to the java.awt.datatransfer.Clipboard methods that allow you to copy and paste items to the system clipboard. Strings are handled natively, and other Object types can be used with a little programming of your own. The big reason to use this class is because it sets the java.awt process up in a daemon thread, which allows your program to terminate properly without a call to System.exit() -- see the JavaDoc comments in the code for more explanation.
Searching for Text in Files
May 30, 2003
A while ago, I did some testing to find out how to search for a String in a file as quickly as possible. This may seem like a fairly rudimentary thing to do, but I was quite surprised at how much variance there was in the speed of many of the obvious solutions, especially when you started looking at large or multiple files. You can use different InputStreams and Readers, adopt different buffering strategies, and so on.
In the end, I found that it seemed to be faster to read a FileInputStream in chunks of 2048 bytes at a time, and compare a byte array representation of my String with the bytes of the file. Just for fun, I wrapped the file searching function (which is called searchFile) in a little Swing application that's pretty easy to use. There are also examples of how to perform some handy little tasks in Swing in there too (like responding to double-clicks and launching threads with your ActionListeners), so some of the other code might be useful to you as well.
(If you're lucky enough to be using Java 1.4 or higher, there's a nice example of how to grep a file using regular expressions and the new java.nio classes in the Sun api docs.)
Manipulating JPEG Images
July 30, 2003
Here's a class I was playing around with that manipulates JPEG images. It's the JpgImage class, and it allows you to do things like rotate, scale, and invert a JPEG image. You can either read an image in from a file or pass a BufferedImage to the constructor. The Sun version of Java 1.2 or higher is required, as this class not only uses some Graphics2d classes, but also a few of the com.sun.image.codec.jpeg classes.
A lot of the methods are trivial wrappers around some of the transform classes, but the rotate() method was a little tricky. See the source code for details.
As an example, I also wrote the JpgResizer class, which is really just a command-line application that calls the methods in the JpgImage class, based on the command-line parameters that you pass. Again, see the source code for details.
Testing ReplaceSubstring Routines
September 17, 2003 (updated March 14, 2003)
This is just a little speed test of a few different routines that can be used to replace all occurrences of a substring within a larger String. More interesting than the functions themselves (StringBuffer was faster...no surprise there) is the testing method. Reflection is used to run all the validation and the speed testing, which makes it very modular.
Normally, for tests of multiple similar functions like this, you end up copying and pasting a lot of redundant code to run the same test against multiple functions. Using the techniques in this example, you can see how Java reflection makes it possible to simply pass the name of the method you want to test, and all the testing code ends up in a single routine that gets called multiple times.
(Added the ReplaceSubstring6 method on March 14, 2004, which is similar to the other methods but checks for a condition where both the original string and the find string are "", in which case the method should return the replace string, not the original string as with the other methods. Thanks to John Marshall for that tip.)
ReplaceSubstringTest.java
ReplaceSubstringTest.class
Terminating Threads and Reacting to Shutdown in Java
November 10, 2003
When you're writing a multi-threaded program in Java, you generally want to add some handling for killing the threads when the program is ready to terminate, especially if your threads are running continuously (or potentially for a very long time) while waiting for an event to occur. For instance, a multi-threaded command-line Java program might be structured similar to this example:
This type of setup should allow our program to kill and cleanup the thread and its resources, as long as the program shuts down the way we're expecting it to. However, what if a user decided to just use Control-C to terminate the program instead? None of the structured clean-up work would get done, and you could be left with a mess. This could happen just as easily with a GUI program if someone kills it at the command-line, despite the fact that you've registered your handlers for java.awt (addWindowListener) or javax.swing (setDefaultCloseOperation) or whatever GUI library you're using.
Luckily, starting with Java 1.3, Sun gave us the ability to register shutdown hooks to handle just such a case. All you have to do is make a call to
Runtime.getRuntime().addShutdownHook(Thread t)
and you're on your way. Here are some good articles to get you started:
http://developer.java.sun.com/developer/TechTips/2000/tt0711.html
http://www.onjava.com/pub/a/onjava/2003/03/26/shutdownhook.html
Once you've got a feel for how addShutdownHook() works, you might want to delve a little deeper with these related articles:
How to effectively handle long-running tasks in Java:
http://builder.com.com/5100-6370_14-1049564-1.html
Writing your own signal handlers in Java (very technical, very cool):
http://www-106.ibm.com/developerworks/ibm/library/i-signalhandling/
Open JAR Files Natively In Windows
October 14, 2004
In case you didn't know, a Java Archive (.jar) file is really just a .zip file with a different extension. Windows 2000 and XP (and I think even ME, if anyone still uses that) came with built-in support for zip files, and you can take advantage of that to open jar files natively in Windows as though they were zip files.
This is convenient not only because you can easily open and navigate the .jar files as though they were folders, but also because Windows will then be able to search within these archive files when you're performing a regular file system search. Very handy for finding .class files buried deep within a .jar.
Technically, the steps to follow are these:
However, if you don't want to follow all those steps you can probably just download this .reg file and run it locally on your machine:
Make sure you reboot after you've run/imported the .reg file, because the changes won't take effect until you restart the machine. Also, you can easily modify the .reg file to register .ear and .war files as zip files too, if you're so inclined. Those also use the zip technique for compression (well, they've got a certain directory structure too, but they're still just zips).