February 9, 2010

Minimal Java for XML Processing

XML Logo
These Java examples show very simple ways to write, validate, and read XML files. Use the examples as tutorials to learn the basics of working with XML.

Catalog of Java examples for XML processing:
Java Get Powered
The examples are presented as complete programs so you can quickly run and test them. For example, to try out the "XML Writer" program, you would download the XmlWriter.java file and execute the following commands:
     $ javac *.java
$ java XmlWriter.class
Code here is Public Domain Software — Free to Use as You Like.


XML Writer
This example program creates a very simple DOM (Document Object Model) containing a list of countries and then writes the DOM out to an XML file.
XmlWriter.java

import java.io.File;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;

public class XmlWriter {

public static void main(String[] args) {
try {
//Sample Data (countries and capitals)
HashMap data = new HashMap();
data.put("Egypt", "Cairo");
data.put("Finland", "Helsinki");
data.put("Japan", "Tokyo");

//Create DOM (with top-level node)
DocumentBuilder xmlBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document xmlDoc = xmlBuilder.newDocument();
Node node = xmlDoc.createElement("countries");
xmlDoc.appendChild(node); //top-level node

//Add Data to DOM
for (String key : data.keySet()) {
Element elem = xmlDoc.createElement("country");
elem.setAttribute("capital", data.get(key)); //attrib
elem.appendChild(xmlDoc.createTextNode(key)); //content
node.appendChild(elem);
}

//Write DOM to XML file
Source source = new DOMSource(xmlDoc);
Result result = new StreamResult(new File("countries.xml"));
Transformer xformer =
TransformerFactory.newInstance().newTransformer();
xformer.setOutputProperty(OutputKeys.INDENT, "yes");
xformer.transform(source, result);
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}

}

View/Download: XmlWriter.java

countries.xml

<?xml version="1.0" encoding="UTF-8"?>
<countries>
<country capital="Helsinki">Finland</country>
<country capital="Cairo">Egypt</country>
<country capital="Tokyo">Japan</country>
</countries>

File Created by Program

Note that using a DOM holds the entire XML tree structure in memory. For large data sets it is often necessary to instead use SAX (Simple API for XML) which uses an event based approach to hold and process only the part of the document that is needed.


XML Validator
This example program validates an XML file against an XSD (XML Schema Definition).
XmlValidator.java

import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.transform.stream.StreamSource;

public class XmlValidator {

public static void main(String[] args) {
try {
StreamSource xsdInput = new StreamSource(new
XmlValidator().getClass().getResourceAsStream("countries.xsd"));
Schema schema = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(xsdInput);
schema.newValidator().validate(new StreamSource(
new File("countries.xml")));
System.out.println("XML file sucessfully validated against XSD.");
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}

}

View/Download: XmlValidator.java

XML Schema Used to Validate XML

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="countries">
<xs:complexType>
<xs:sequence>
<xs:element name="country" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="country">
<xs:complexType mixed="true">
<xs:attribute name="capital" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>

View/Download: countries.xsd

cvc-complex-type.2.4.a: Invalid content was found starting
with element 'region'. One of '{"":country}' is expected.

Program Output

The above error message was generated from an input file (countries.xml) containing invalid XML.  A <region> tag was used where a <country> tag was expected.


XML Reader
This example program reads an XML file and prints out the name of each node along with its first attribute.
XmlReader.java

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;

public class XmlReader {

static void processNode(Node node) {
String msg = "node --> " + node.getNodeName();
String nodeContent = node.getFirstChild().getNodeValue();
if (!nodeContent.equals("\n")) //check if has text content
msg = msg + " | value: " + nodeContent; //add text content
if (node.hasAttributes()) //add first attrib if exists
msg = msg + " | attrib: " +
node.getAttributes().item(0).getNodeName() + "=" +
node.getAttributes().item(0).getNodeValue();
System.out.println(msg); //display node information
for (Node subNode = node.getFirstChild(); subNode != null;
subNode = subNode.getNextSibling())
if (subNode.getNodeType() == Node.ELEMENT_NODE)
processNode(subNode);
}

public static void main(String[] args) {
try {
DocumentBuilder xmlBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document xmlDoc = xmlBuilder.parse(new File("countries.xml"));
processNode(xmlDoc.getDocumentElement());
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}

}

View/Download: XmlReader.java

node --> countries
node --> country | value: Finland | attrib: capital=Helsinki
node --> country | value: Egypt | attrib: capital=Cairo
node --> country | value: Japan | attrib: capital=Tokyo

Program Output (input file: countries.xml)



Further Reading

Elsewhere:

January 31, 2010

JavaScript Snippets for Dynamic Web Pages

There are a ton of unnecessarily complicated JavaScript examples strewn about the Internet. In an attempt to counter that, here are a few simplified examples of using JavaScript to accomplish common tasks.

Catalog of JavaScript Snippets:To try out a snippet, click the link for the example listed below the snippet. Code here is Public Domain Software — Free to Use as You Like.


Show/Hide Toggle
JavaScript can be used to show and hide an object on a web page with each click by the user. This JavaScript snippet finds the display status of the element and flips the status from "none" (hidden) to "block" (visible) or from "block" to "none".
JavaScript

function toggle(elemName) {
var s = document.getElementById(elemName).style;
s.display = s.display == 'none' ? 'block' : 'none';
}




Read URL Parameters
JavaScript can be used to read URL parameters. This JavaScript snippet reads the name/value pairs appended to a URL and stores the values in an array named params.
JavaScript

var params = new Array();
var keyvals = location.search.substring(1).split('&');
for (count in keyvals) {
keyval = keyvals[count].split('=');
params[keyval[0]] = keyval[1];
}




Set and Get Cookie Value
JavaScript can be used to set and get browser cookies. This JavaScript snippet contains two functions — one to save the cookie value and the second to read the value back.
JavaScript

function setCookie(key, value) {
var expires = new Date();
expires.setTime(expires.getTime() + 31536000000); //1 year
document.cookie = key + '=' + value + ';expires=' + expires.toUTCString();
}

function getCookie(key) {
var keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
}




Further Reading

Elsewhere:

July 4, 2009

Don't Touch that DSL Installation CD

Phone Wiring
Phone Wiring
When you purchase DSL (Digital Subscriber Line) broadband Internet service from an ISP (Internet Service Provider) such as your phone company, the ISP almost always provides you with an installation CD. Ever wonder what it installs? It installs the ISP's branding all over your computer.

DSL Modem
DSL Modem
Besides electrical power and telephone wiring to the jack, all the DSL modem needs to access the DSL line is your DSL username and your DSL password. The DSL username and DSL password should be saved to your router not your computer, and that is why you do not need to install any DSL software on your computer. Additionally, the router provides critical network firewall protection and makes it easy to share your DSL connection with multiple computers. Contrary to what your ISP will tell you, there is no need to install any software on your computer. Doing so will just gunk up your computer. Don't do it.

Ethernet Cable
Ethernet Cable
Setup without Installing Software
Instead, use your computer's web browser to access the router's configuration web page (administration console) to enter and save your DSL username and DSL password.

Router
Router
1) Get Your DSL Login Information
Using a computer with Internet access, go to your ISP's web site and create or register your DSL account. Take note of your DSL username and DSL password. (Note that some ISPs may have you create your DSL account via the DSL connection.)

2) Setup Equipment
Connect up all your equipment. The DSL modem connects to the phone jack with a regular telephone wire (RJ-11). The router connects to the DSL modem and to the computer each with an Ethernet cable (Cat5). Your equipment setup can be simplified by using a combination DSL modem device with a build-in router.

Phone Jack ←→ DSL Modem ←→ Router ←→ Computer(s)

Equipment Connections

3) Configure Router to do DSL Login
Use your web browser to log into the router configuration web page.

Common Router Configuration Web Pages

Router ManufactureAdministration ConsoleUsernamePassword
2wire192.168.1.254
homeportal
admin(blank)
Apple10.0.1.1(blank)public
(blank)
ASUS192.168.1.1adminadmin
Belkin192.168.2.1(blank)(blank)
admin
D-Link192.168.0.1adminadmin
(blank)
Linksys192.168.1.1admin
(blank)
admin
NETGEAR192.168.0.1adminpassword
TRENDnet192.168.1.1adminadmin
Zoom10.0.0.2adminzooomadsl


Note that manufactures sometimes change the default settings, so many older routers have different default settings. For an extensive list of router logins, visit: routerpasswords.com

Each manufacturer's router configuration web page is a little different, but the basic configuration steps are usually the same.

Configuration Steps:
  1. Find the DSL automatic settings detection option and run it
  2. If you have your DSL username and DSL password, enter them into the DSL login fields.
  3. Save your settings.
  4. Look for a status message or status page and check that the DSL connection is active.
  5. Browse to a news web site to verify you are connected to the Internet.
  6. If you are presented with a web page to create your DSL account, do that and then go back to the router configuration web pages and save your DSL username and DSL password.
Once you have tested your Internet connection, you should consider using the router configuration web page to change your router's administrator password and to setup your wireless network (Wi-FI).

Still Trying to Trick You
Some ISPs are so desperate to force you to install their DSL software on your computer that they will block your Internet access with a software download web page. ISPs generally have software only for Mac OS X and Microsoft Windows. To support other operating systems, such as Ubuntu, the ISP will have an alternate activation or registration option that does not involve downloading and installing their software.

Alternate Registration/Activation Web Pages

ISPBackdoor
AT&Thttp://144.160.11.35/register

If you are running Mac OS X or Microsoft Windows, one option is to temporarily customize your browser so that it reports a different operating system.

On Mac OS X:
      SafariPreferencesAdvanced → Check option to Show Develop menu in menu bar → close window → DevelopUser AgentOther... → Replace all text with: UbuntuOK

For other systems:
      User Agent Switcher

Router Installation CD
Your router probably also came with an install CD. As with the ISP install CD, don't touch it.

Fewer Moving Parts
Avoiding your ISP's unnecessary DSL software will keep your machine cleaner and reduce the likelihood encountering problems in the future. Plus, having the router manage the DSL login information makes using multiple computers easier.


June 10, 2009

Java Snippets

Java Snippets
Some people learn best through examples. With that in mind, here are some stripped-down simplified examples of Java code to perform various tasks. These snippets are not robust enterprise-ready patterns nor do they do not represent best practices. Rather, they are barebones examples to help you get up and running as quickly as possible.

Catalog of Java Snippets:
Java Get Powered
The snippets are presented as complete programs so you can quickly run and test them. For example, to try out the "HashMap Loop" program, you would download the HashMapLoop.java file and execute the following commands:
     $ javac *.java
$ java HashMapLoop.class
Code here is Public Domain Software — Free to Use as You Like.


HashMap Loop
HashMaps are convenient for storing key-value pairs. This snippet iterates over a java.util.HashMap collection without explicitly creating an iterator.
HashMapLoop.java

import java.util.HashMap;

public class HashMapLoop {

public static void main(String[] args) {
HashMap<String, String> data = new HashMap<String, String>();
data.put("Color", "Green");
data.put("Size", "Medium");
data.put("Speed", "Fast");
for (String key : data.keySet())
System.out.println(key + " --> " + data.get(key));
}

}

View/Download: HashMapLoop.java

Color --> Green
Speed --> Fast
Size --> Medium

Program Output



TopMap Element Tracker
This snippet keeps track of the top (heaviest, furthest, oldest, longest, loudest, fastest, etc.) elements as your program processes the elements. Instead of holding onto all the elements, this snippet uses java.util.TreeMap to hold only the top elements.

The code below demonstrates TopMap with a simple example of tracking the largest islands by land mass.
TopMap.java

import java.util.*;

public class TopMap extends TreeMap {

private final int maxElems;

public TopMap(int maxNumberElements) {
super(Collections.reverseOrder());
maxElems = maxNumberElements;
}

@Override
public V put(Integer key, V value) {
if (size() < maxElems || key > lastKey())
super.put(key, value);
if (size() > maxElems)
remove(lastKey());
return value;
}

public static void main(String[] args) {
TreeMap islands = new TopMap(3);
islands.put( 507000, "Baffin");
islands.put( 726000, "Borneo");
islands.put(2131000, "Greenland");
islands.put( 578000, "Madagascar");
islands.put( 800000, "New Guinea");
System.out.println("Three Largest Islands:");
for (Map.Entry island : islands.entrySet())
System.out.println(island.getKey() + " sq km - " + island.getValue());
}

}

View/Download: TopMap.java

Three Largest Islands:
2131000 sq km - Greenland
800000 sq km - New Guinea
726000 sq km - Borneo

Program Output

Note that this solution does not support duplicates because TreeMap itself does not support duplicates. If your data contains ties (where two or more keys are equal), use TopMultiMap (which incorporates a special comparator to hide duplicates) or use TopElements (which incorporates lists to keep track of possible ties).


Web Page Reader
This snippet reads the contents of a web page (example: WebPageReader.html).
WebPageReader.java

import java.io.*;
import java.net.*;

public class WebPageReader {

public static void main(String[] args) {
String url = "http://www.centerkey.com/files/snippets/WebPageReader.html";
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new URL(url).openStream()));
for (String s = reader.readLine(); s != null; s = reader.readLine())
System.out.println(s);
reader.close();
}
catch (Exception e) {
System.out.println(e.toString());
}
}

}

View/Download: WebPageReader.java

<html>
<head><title>Simple Web Page</title></head>
<bogy><h1>WebPageReader Test</h1></body>
</html>

Program Output

This approach can also be used to read text data, such as a product's current version number, from a web site.


Desktop Browser Launch
This snippet opens a web page in the user's default browser.
DesktopBrowser.java

public class DesktopBrowser {

public static void main(String[] args) {
String url = "http://www.google.com";
try {
java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
}
catch (java.io.IOException e) {
System.out.println(e.getMessage());
}
}

}

View/Download: WebPageReader.java

This code requires Java 6 or later.


Further Reading
Elsewhere:

May 16, 2009

Set JAVA_HOME in a Windows Command Script

Apache Ant is generally the preferred tool for building Java applications, and most IDEs support building with Ant right from the IDE. However, when you need to build your Java application outside of the IDE, it can be handy to have a script kick off Ant.

On Microsoft Windows the script needs to know the location of the JDK and Ant, which generally entails:
  • Relying on environment variables to be set correctly or
  • Hardcoding the path locations

Both approaches are brittle and likely to result in maintenance and support headaches down the road. Additionally, hardcoding the paths assumes all the developers are running the same versions of the JDK and Ant. These limitations are insignificant for a centrally managed commercial software organization, but they can be problematic for a distributed open source project.

DOS For Command
Fortunately, it's easy to write a Command Script (.cmd) batch file using the DOS for command that automatically determines the path to the most current versions of the JDK and Ant. To test out the for command, try the following at the Windows Command Prompt.

Command Prompt Demonstration:
C:\>for /d %i in ("\Program Files\Java\jdk*") do set JAVA_HOME=%i
C:\>set JAVA_HOME

You should see a result similar to:
       JAVA_HOME=\Program Files\Java\jdk1.6.0_13

Command Script Solution
To make it easy to launch Ant, put the following build.cmd file into the same folder as your build.xml Ant configuration file.

The build.cmd File:
@echo off
::::::::::::::::::::::::::::::::::::
:: build.cmd (v1.0) ::
:: Microsoft Windows Build Script ::
::::::::::::::::::::::::::::::::::::

:: Set JAVA_HOME
for /d %%i in ("\Program Files\Java\jdk*") do set JAVA_HOME=%%i

:: set ANT_HOME
for /d %%i in ("\Apps\Ant\apache-ant*") do set ANT_HOME=%%i

:: Display Variables and Launch Ant
set JAVA_HOME
set ANT_HOME
call %ANT_HOME%\bin\ant build
pause

View/Download: build.cmd

Now to build your project, double-click the build.cmd file.

While the script does not hardcode the JDK and Ant versions, it does require that the JDK is installed into the default location and that Ant in installed (copied) into the \Apps\Ant folder.

Alternative Approach
If you prefer to be more robust in your detection of the JDK home, you can use the DOS reg query command to read the Windows Registry information to locate the JDK. In the build.cmd file, replace the line that sets JAVA_HOME with the lines below.

Use Windows Registry to Set JAVA_HOME:
:: Set JAVA_HOME
set KeyName=HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit
set Cmd=reg query "%KeyName%" /s
for /f "tokens=2*" %%i in ('%Cmd% ^| find "JavaHome"') do set JAVA_HOME=%%j

View/Download: set-java-home.cmd

The output of the reg query is piped through find to single out the desired key value. The third token (represented by %%j) on the line is the path.

Simplify
By having build.cmd auto-detect the JDK and Ant, you can simplify the steps for new developers looking to contribute to your open source project.

Mac OS X Shell Script
To kick off Ant on a Mac, you can use this shell script:
#!/bin/sh
#############################
## Mac OS X Build Script ##
#############################

cd `dirname $0`
ant build

View/Download: build.sh.command

This script is simple because Apple bundles the JDK and Ant with Mac OS X.


April 26, 2009

Save Mac Data with Snap Backup

For most Mac users, Apple's Time Machine is the best solution for backing up their data. But for those who desire more control over exactly what data to backup, there's Snap Backup. If you backup only your personal data instead of your entire hard drive, your backup files can be relatively small and often even fit on a USB flash drive (memory stick).

The trick is knowing exactly what folders and files to backup.

Follow the steps below to setup Snap Backup on your Mac OS X system to backup your:

  • Documents Folder
  • Desktop
  • Safari Bookmarks
  • Address Book Data
  • iCal Data
  • Mail (Mail.app) Data

1) Install Snap Backup
Snap Backup is a free open source utility for archiving your data.

Get it at: www.snapbackup.com/download

2) Configure Snap Backup
Go into the Applications folder and launch Snap Backup.

Your Documents folder and Desktop will be listed in the "Source: Data to Backup" section by default. Now you need to add your Safari bookmarks. Do this by clicking the Add File button and navigating to and opening the Library/Safari/Bookmarks.plist file.

Repeat the add process for each of following folders and files until they are all listed on the Snap Backup screen.

SourceDescriptionData Location (under Home folder)Type
Documents FolderWork filesDocumentsfolder
DesktopWork filesDesktopfolder
SafariBookmarksLibrary/Safari/Bookmarks.plistfile
Address BookContactsLibrary/Application Support/AddressBookfolder
iCalMeetingsLibrary/Calendarsfolder
MailE-mailLibrary/Mail
Library/Preferences/com.apple.mail.plist
folder
file

Data Location is relative to your Home folder (/Users/[YourUserName]). For example, the full path for the Documents folder on my system is: /Users/dem/Documents

Click the Save Settings button.

3) Prepare for Backup
Optional: To make your e-mail more compact, you can empty your mail Trash (Mailbox &rarr Erase Deleted Message). Additionally, you should delete unneeded attachments (Message &rarr Remove Attachments).

Quit Address Book, iCal, and Mail.

4) Perform Backup
In Snap Backup, click the Backup Now button to perform the backup.

Be sure to perform backups on a regular basis, and periodically copy your backup files to a USB flash drive, external hard drive, or other remote storage device.



In the event you need to restore your data from a backup, follow the steps below.

Restore Steps:

  1. Quit Address Book, iCal, and Mail
  2. Use Finder to navigate to your Backup folder
  3. Identify the backup file you wish to restore and double-click it (this will reveal the contents of the backup file)
  4. Drag the contents into your Home folder
  5. Launch Address Book, iCal, and Mail and check that your data has been restored.

If you have a suggestion for an enhancement to Snap Backup, please let us know using the feedback form.


March 2, 2008

Outlook Done Button

A strategy called Inbox Zero centers around a "process to zero" approach to keeping your e-mail inbox empty. You can use the Inbox Zero strategy to save yourself from e-mail overload and significantly reduce the amount time you waste rereading e-mails and sifting through an overflowing, stale inbox.
Many of your e-mail messages can simply be deleted after you have read them, and other messages should be moved into specific folders for future action or reference. However, it is likely that the majority of your incoming messages simply need to be quickly read once and then moved out of the way into some kind of general "Done" folder. These are the messages that require no action and are not worthy of filing into any specific folder, but it would be unwise to immediately delete them.

Many e-mail applications make the process of moving read e-mail into a "Done" folder very easy with a single button click or keystroke -- not Microsoft Outlook. Microsoft has an amazing ability to make obvious and simple tasks become painfully convoluted and cumbersome. Fortunately, there is a way to
configure Outlook to enable you to "process to zero" without being forced to use the mouse to drag each and every message into a "Done" folder.

Follow the steps below to create an Outlook macro which implements a Done button. The first step guides you though creating a certificate for you macro so the macro will be "trusted" on you computer. Then you will create the macro itself and a corresponding Done folder. Lastly, customize the toolbar to add a button which runs the macro.

Steps:

A) Create a Personal Digital Certificate
Start → Programs → Microsoft Office → Microsoft Office Tools → Digital Certificate for VBA Projects → Your certificate's name: Personal Certificate → OK → OK


B) Create Macro from Microsoft Outlook
1: Tools → Macro → Macros...
2: In "Macro Name:" field, enter "MoveToDone" and click "Create"
3: Enter the following code into the VBA editor:
Sub MoveToDone()
Set DoneFolder = Application.GetNamespace("MAPI"). _
GetDefaultFolder(olFolderInbox).Parent.Folders("Done")
For Each Msg In ActiveExplorer.Selection
Msg.Move DoneFolder
Next Msg
End Sub


4: Tools → Digital Signature... → Choose... → Select "Personal Certificate" → OK → OK
5: File → Save
6: File → Close and Return to Microsoft Outlook Office

C) Create a Done Folder
File → New → Folder... → Name: Done → Select Mailbox (top of list) → OK

D) Add Done Button
Tools → Customize... → Commands → Macros → Drag Project1.MoveToDone onto the toolbar → Context menu (right-click) for the new MoveToDone button → Set "Name:" to Done → Close


E) Enable Macros
After restating Outlook and clicking your new "Done" button, you will be prompted to allow the button to run.

Check the "Always trust macros from this publisher" option and then click "Enable Macros".

Now you can move a message from your Inbox into the Done folder with the "Done" button.

You might also find it valuable to use the "Outbox" as your to do list. If you need to take action on the e-mail, reply to the message even if you do not immediately send your reply. That way, your "Outbox" becomes your to do list.

Leveraging your Outbox as your to do list and using your new Done button, you can maintain an empty Inbox and focus on doing real work instead of suffering from e-mail overload.