Friday, February 12, 2010

Swapping Variables

Here is a neat way you can swap two integer variables, x and y, without using an intermediary temporary variable:
If, x = 5 and y = 7, then:

x = x + y = 12
y = x - y = 5
x = x - y = 7

So, x = 7 and y = 5.
However, I would recommend that you keep your code simple and understandable, by using a temporary variable, as follows:
If, x = 5 and y = 7, then:

temp = x = 5
x = y = 7
y = temp = 5

So, x = 7 and y = 5.

Tuesday, February 09, 2010

Pidgin SIPE Plugin for OCS

We recently switched from Reuters Messaging to Microsoft Office Communicator 2007 (OCS) at work and I was disappointed to find that OCS:
  • does not have tabbed conversation windows, which leads to a cluttered desktop and cramped taskbar.
  • does not keep conversation history logs. I believe this feature only works if you use Outlook and we use Lotus Notes.
In order to get around these issues, I am now using Pidgin with a plugin to connect to OCS and don't need the OCS client anymore!

Install SIPE Plugin for Pidgin:
This is how you can install the plugin to use Pidgin for OCS:

  • Download and install Pidgin from here.
  • Download SIPE from here.
  • Unzip pidgin-sipe-1.8.0-msi.zip and run pidgin-sipe-1.8.0.msi to install it.
  • Start the Pidgin client.
  • Add a new Account with the following details:
    • Protocol: Office Communicator
    • Username: firstname.lastname@company.com
    • Login user: firstname.lastname@company.com
    • Password: xpPassword
    • On the Advanced tab, tick "Use Kerberos" and untick "Use Single Sign-On".
That's all you need to do to connect to OCS from Pidgin. You can now enjoyed tabbed conversations and view logs stored in %APPDATA%\.purple\logs\sipe.

You can also add the following useful plugins to Pidgin:

  • Text replacement
  • Guifications
  • Pidgin GTK+ Theme Control - you can download themes and install using Theme Selector (which should be present in your Start Menu).

Wednesday, February 03, 2010

XMLBeans for Handling XML in Java

XMLBeans is a useful library which allows you to convert XML files into Java objects, call methods on the objects and then write the objects back to XML. This post shows you how you can use XMLBeans to:
  • Generate an XSD schema from an XML file
  • Compile the schema into Java classes
  • Use the classes to create an XML structure
  • Use the classes to read an XML file
Generating a Schema from an XML File
If you have an XML file, you can generate a schema using the inst2xsd command. For example, say you have the following xml:
<books>
    <book id="1">
        <title>Snow Crash</title>
        <author>Neal Stephenson</author>
    </book>
    <book id="2">
        <title>Neuromancer</title>
        <author>William Gibson</author>
    </book>
</books>
You can generate an XSD, using the following different design types: Russian Doll, Salami Slice or Venetian Blind. This is what the output looks like:

Russian Doll Design:

inst2xsd -design rd -enumerations never C:\temp\books.xml

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="books">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="title"/>
              <xs:element type="xs:string" name="author"/>
            </xs:sequence>
            <xs:attribute type="xs:byte" name="id" use="optional"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
Salami Slice Design:
inst2xsd -design ss -enumerations never C:\temp\books.xml

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="books">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="book" maxOccurs="unbounded" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="author" type="xs:string"/>
  <xs:element name="title" type="xs:string"/>
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="title"/>
        <xs:element ref="author"/>
      </xs:sequence>
      <xs:attribute type="xs:byte" name="id" use="optional"/>
    </xs:complexType>
  </xs:element>
</xs:schema>
Venetian Blind Design:
inst2xsd -design vb -enumerations never C:\temp\books.xml

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="books" type="booksType"/>
  <xs:complexType name="booksType">
    <xs:sequence>
      <xs:element type="bookType" name="book" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="bookType">
    <xs:sequence>
      <xs:element type="xs:string" name="title"/>
      <xs:element type="xs:string" name="author"/>
    </xs:sequence>
    <xs:attribute type="xs:byte" name="id" use="optional"/>
  </xs:complexType>
</xs:schema>
Compiling a Schema into Java Classes
Once you have generated a schema, you can use the Maven xmlbeans plugin to compile it into Java classes:
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>xmlbeans-maven-plugin</artifactId>
  <version>2.3.2</version>
  <executions>
    <execution>
      <goals>
        <goal>xmlbeans</goal>
      </goals>
    </execution>
  </executions>
  <inherited>true</inherited>
  <configuration>
    <schemaDirectory>src/main/xsd</schemaDirectory>
    <sourceSchemas>
      <sourceSchema>books.xsd</sourceSchema>
    </sourceSchemas>
    <sourceGenerationDirectory>target/generated-sources/xmlbeans</sourceGenerationDirectory>
  </configuration>
</plugin>
You can also use the scomp command which will create a jar file containing the compiled classes.
C:\xmlbeans-2.4.0\bin> scomp -compiler %JAVA_HOME%\bin\javac books.xsd
Creating an XML Document Using the Compiled Classes
Add the jars to your classpath. Build an XML document as shown below (note that I am using the schema with the Russian Doll design. Different design types will produce different classes.):
BooksDocument doc = BooksDocument.Factory.newInstance();
Books books = doc.addNewBooks();
Book book = books.addNewBook();
book.setId((byte) 1);
book.setAuthor("Isaac Asimov");
book.setTitle("I, Robot");
System.out.println(doc.toString());
Produces:
<books>
  <book id="1">
    <title>I, Robot</title>
    <author>Isaac Asimov</author>
  </book>
</books>
Reading an XML Document Using the Compiled Classes
You can read an xml document and parse it into objects in the following way:
BooksDocument doc = BooksDocument.Factory.parse(
                    new File("C:\\temp\\books.xml"));
Books books = doc.getBooks();
Book[] bookArr = books.getBookArray();
for (Book book : bookArr) {
 String author = book.getAuthor();
 String title = book.getTitle();
 byte id = book.getId();
 System.out.println(author + '\t' + title);
}

Thursday, January 28, 2010

Find the version number of a .class file

If you see the error:
 java.lang.UnsupportedClassVersionError: Bad version number in .class file
it means that the Java ClassLoader cannot load a certain class because it has been compiled using a different version of the JDK. For example, you might see this error if your application has been compiled using Java 1.5, but an external library you are calling has been compiled using 1.6.

You can use the javap command to find out what the version number of a class file is:

sharfah@starship:~> javap -v MyApp | grep version
  minor version: 0
  major version: 50
50 refers to Java 1.6, while 49 refers to Java 1.5.

Tuesday, January 19, 2010

Difference between $*, $@, "$*" and "$@"

They are all related to "all the arguments to the shell", but behave differently. The following script demonstrates each one of $*, $@, "$@" and "$*" in turn by echoing out the arguments passed in:
#! /bin/bash

echo +--- Using "\$*"

cnt=1
for i in $*
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done

echo +--- Using \"\$*\"

cnt=1
for i in "$*"
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done

echo +--- Using "\$@"

cnt=1
for i in $@
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done

echo +--- Using \"\$@\"

cnt=1
for i in "$@"
do
  echo arg$cnt: $i
  cnt=$(($cnt+1))
done
Running the script, produces the following output:
sharfah@starship:~> echoArgs.sh  mars "kit kat" twix
+--- Using $*
arg1: mars
arg2: kit
arg3: kat
arg4: twix
+--- Using "$*"
arg1: mars kit kat twix
+--- Using $@
arg1: mars
arg2: kit
arg3: kat
arg4: twix
+--- Using "$@"
arg1: mars
arg2: kit kat
arg3: twix
When unquoted, $* and $@ do the same thing. They treat each "word" (sequence of non-whitespace characters) as a separate argument. This leads to the single argument "kit kat" being broken into two which may not be desired. When quoted, $* and $@ behave differently. "$*" treats the entire argument list as a single argument, but "$@" treats the arguments just as they were when passed in.

So, which should you use? In almost all cases you would use "$@" in order to preserve arguments with spaces (or quoted arguments) when being passed in on the command line or from one script to another. Never use the unquoted $* or $@ unless you are absolutely sure that you won't need to deal with arguments with spaces in them. If you need to combine all arguments into one, use "$*".