Tuesday, December 26, 2006

Java: RCP Article 2

While not necessarily my intention, I have neglected to write the later few articles in my RCP tutorial. Holiday duties in conjunction with new job responsibilities have eaten away at my free time. Here I am, sitting with the Gamecube version of Zelda, Twilight Princess (no Wii here, I’m sitting that one out until the villainous holiday mobs quit snatching every shipment up 10 minutes after store opening, but I’m not complaining, this is by far one of the most beautiful GC games, if not last gen game on any platform, and some next-gen games, I have ever laid eyes on), Final Fantasy XII (by far, one of the most boring story lines I have ever played, but I will stick it out since it is a Final Fantasy damnit), and Metal Gear Solid: Portable Ops (one of the best friggin hand-held games I have every played in my life, too bad it is marred with the horrid control schema that comes from the poor ergonomic design that is the PSP, but strangely addicting) being largely unplayed due to this lack of leisure time.

So, here is part two of my RCP tutorial. Last time I build a small RCP application that grabbed a list of all my files on the root of my drive (in my case, C:/) and displayed them in a tree. While I had intended to build a JAR file to incorporate with my app that used the Google web API to query Google, wouldn’t you know it, Google went and dropped their web API. THE MODEL for web services, and they drop it. Others believe that this is a signal of the end of the web-services bubble. Personally, I think it’s a sign that Google is become less of the good guy and more like “Evil” shit-heads more concerned with the bottom line. Regardless of motive, I have to change course here…

So as a substitute to the formerly awesome Google web service, I had to build my own simple web service using Tomcat. For this article, I will build a simple web service that returns the string “My Test Webservice” in Eclipse. Nothing fancy, I just didn’t feel like going with Hello World.

First thing first, make sure you have the Eclipse Web Tools project installed. For me, I am using the BIRT All-In-One install of Eclipse 3.2 Catalina, with WTP installed separately via the update manager. The WTP also has a separate All-in-One package. Make sure you also have configured a Server and Server Runtime for testing and debugging. Certain aspects of the application development did not work properly without them. So here, I will walk through the process of creating the server.

First, I went up to File/New and chose Other. I chose the Server category, and chose a Server project. Since I am using Apache Tomcat 4.1 (which I keep around for other projects compatibility) I choose Tomcat 4.1 as my server type. The next screen sets up the server runtime, so I need to set the install directory for Tomcat 4.1, and I set up the JRE location to where my JDK is installed. I am using Java 1.5.09, which when I set the directory, the JRE Name and JRE Libraries automatically filled themselves out. Once setup, I just click Next, and then Finish to complete the setup. Now, I can start and stop this server configuration by going up to Window, Show View, Other, and choose server. A server tab opens up in the same area where the Console tab and the Properties tab are.


Figure 1. Server Configuration


Figure 2. Servers Tab

With that installed, I created a new Dynamic Web Project called MyWebService. I make sure that my Target Runtime is set to the Runtime configured in my server project configuration. On the next screen, I do not set any other configurations and keep things default (Dynamic Web Module and Java are checked, JavaServer faces is not). I keep the Context Root set to MyWebService and the content directory to default. Once done I click Finish.


Figure 3. New Dynamic Web Project

With my project created, I create a new Java class in my project called MyWebService in the com.digiassn.blogspot package. I write the following code for this class:

package com.digiassn.blogspot;

public class MyWebService
{
public String outputResponse()
{
return "My Test Webservice";
}
}

Once done, I save the file, then in the Project Explorer, I right-mouse click on the MyWebService.java file, go to Web Services, and choose Create Web Service. I use the following settings:


Figure 4. Web Service Configuration

I also choose to create a WSDL file to for other future programs to consume this service, which will include the finalization of the RCP application. On the next few screens, I have to start the Server in order to proceed, which publishes the project. I also choose not to publish to a UDDI registry.

Now, I want to test my installation, so I go to the following URL:

http://localhost:8080/MyWebService/services/MyWebService

And the WSDL file is located here:

http://localhost:8080/MyWebService/wsdl/MyWebService.wsdl

So now I want to test my web service to make sure it works. This is actually incredibly easy in Eclipse with WTP, a lot easier than I would have thought. One way I can test is to right-mouse click on the MyWebService.java file, choose web service, and select Generate Sample JSP. I get a Web Services Test Client page with some buttons and some panes with the example outputs. I can also go to the WebContent/wsdl/MyWebService.wsdl file and choose “Test with Web Services Explorer”. From here, I can launch various test pages and view the SOAP envelope messages that get sent back and forth.

Now I can publish to the server and I have my web service to consume in the RCP application.

Tuesday, December 12, 2006

Windows: Command Line From Here

I can't remember where exactly I found this at, but below is a useful little registry hack that will add a "DOS Prompt From Here" option in Explorer whenever you right-mouse click on a folder.

REGEDIT4
BLANK LINE GOES HERE
[HKEY_CLASSES_ROOT\Directory\shell\DosHere]
@="Command &Prompt:"
BLANK LINE GOES HERE
[HKEY_CLASSES_ROOT\Directory\shell\DosHere\command]
@="C:\\WINNT\\SYSTEM32\\cmd.exe /k cd \"%1\""
BLANK LINE GOES HERE
[HKEY_CLASSES_ROOT\Drive\shell\DosHere]
@="DOS &Prompt Here"
BLANK LINE GOES HERE
[HKEY_CLASSES_ROOT\Drive\shell\DosHere\command]
@="C:\\WINNT\\SYSTEM32\\cmd.exe /k cd \"%1\""

Monday, December 11, 2006

Java: JaxB Part 3 - Implementing JaxB Classes In Java

The third and final part of the JaxB article is here. Previously, I had created an XML schema using Eclipse Web Tools XML Schema Designer, then I used JaxB to create a set of Java classes for use inside of a Java project. So now comes the final part, the project itself…

Few things to note, then I will post the code. First, Eclipse, for some “odd” reason, would not recognize the JaxB generated files in my project folder until I Right-Mouse Clicked on the project, chose Go-Into, and then refreshed. Not sure what the deal was with that. Also, I had to add all the JAR files under the following directories:
C:\Sun\jwsdp-2.0\jwsdp-shared\lib
C:\Sun\jwsdp-2.0\jaxb\lib
C:\Sun\jwsdp-2.0\sjsxp\lib

But with that out of the way, I created a new Java Class called CreateXMLFileFromSystem in a package called com.digiassn.blogspot.filestructure.
The code is below:
package com.digiassn.blogspot.filestructure;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.GregorianCalendar;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;

public class CreateXMLFileFromSystem {

private static void populateFiles(final ObjectFactory factory, final Lfile parent) {
// Get the list of files in the current folder, and store in
// the files variable
final String[] files = new File(parent.getPath()).list();

// For each of the files, check if it is a directory, and add
// to the tree object
for (final String temp : files)
// Try statement added. Reason being, if the current file has
// special access permissions, Java does not handle correctly
// and causes a runtime exception and causes a stop in processing
try {
// Get current file
final File f = new File(parent.getPath() + "/" + temp);

// Create the local file based on our current file
final Lfile t = factory.createLfile();

// Set all attributes for the file
t.setName(f.getName());
t.setIsDirectory(f.isDirectory());
t.setPath(f.getPath());
t.setSize(f.length());

// Setting the time requires the use of the XMLGregorianCalendar
// object
// so here we will create a temporary gregoriancalendar
// and set up the XMLGregorian using the constructor that
// supports
// Gregorian calendar
final GregorianCalendar tempDate = new GregorianCalendar();
tempDate.setTimeInMillis(f.lastModified());

t.setDateLastUpdate(DatatypeFactory.newInstance()
.newXMLGregorianCalendar(tempDate));

// Check if it is a directory
if (f.isDirectory()) {
// If this is a directory, it will have
// sub directories, so add a new
// FilesInFolder object
t.subFiles = factory.createFilesInFolder();

// Make a recursive call, populating LFile with
// all child directories
populateFiles(factory, t);
}

// Go ahead and add to the parent
parent.getSubFiles().getFiles().add(t);
} catch (final DatatypeConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (final RuntimeException e) {
// Do nothing
}
}

public static void main(final String[] args) {
try {
// Setup the JAXBContent and Marshaller
final JAXBContext jcontext = JAXBContext
.newInstance("com.digiassn.blogspot.filestructure");
final Marshaller m = jcontext.createMarshaller();

// Setup the file objects for outputting to our XML file
final File xmlOutput = new File("fileList.xml");
final FileOutputStream outputFile = new FileOutputStream(xmlOutput);

// Create the factory object that will instantiate the JAXB created
// XML handler objects
final ObjectFactory factory = new ObjectFactory();

// Create the JAXB generated classes
final FilesInFolder root = factory.createFilesInFolder();
final Lfile currentFile = factory.createLfile();

// Set our current file to the root of C and add a new FilesInFolder
// object to the subfiles variable since we will "always" have
// subfiles
// and folders in the root of C
currentFile.setName("C:/");
currentFile.setPath("C:/");
currentFile.setIsDirectory(Boolean.TRUE);
currentFile.setReadOnly(Boolean.FALSE);
currentFile.setSize(0);
currentFile.subFiles = factory.createFilesInFolder();

// Start the recursive function calls on our current file. Once complete,
//The currentfile will have all child entries populated in the object
populateFiles(factory, currentFile);

// Add the C:/ file entry and all subsequent child nodes to the
// root element FilesInFolder object in the JaxB class
root.getFiles().add(currentFile);

// Create the JAXB handler and put the Root file as the initial
// constructingg XML element. Since it has already been built, we
// do not need to do anything else
final JAXBElement<FilesInFolder> ds = factory
.createDirectoryStructure(root);

// Set the Formatted Output option to true (trust me, after sitting
// for over an hour and having to increase the JVM heap to over a
// gig just
// to get Eclipses XML editor to even open this file, its easier to
// set formatted output and open in the much less memory hungry VI
// to confirm
// propert output
//
// Once that property is set, write out the file.
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(ds, outputFile);
} catch (final FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (final JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}



As you can see, using JaxB is incredibly easy. For an example like this, however, the resulting file was huge, in the area of 80 Megs to list my file structure. Perhaps XML is not the best format to store that information, but since it is structured it does provide a good example. Opening the resulting file in Eclipse, however, crashed Eclipse with a Out of Heap error, which caused me to have to up the heap space in Eclipse to view the file using the XML viewer. Notice I use the JAXB_FORMATTED_OUTPUT option in the marshaller. The reason being, opening that file in VI proved to be a better option than using Eclipse, and without the Formatted Output option, I ended up with a huge XML file all run together on one line.

Sunday, December 10, 2006

Java: JaxB Part 2 - Using JaxB to Create Java Classes from an XML Schema

Last article I created a XML Schema to use in my example program. I created an XML file that would represent the file structure. My next step in developing my example application is to run JaxB to create a series of Java classes to create the XML file.

The JaxB implementation I used was part of the Java Web Services Developer Pack 2.0, which I installed to directory C:\Sun\jwsdp-2.0

Once installed, I set the following environment variables:

JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09
ANT_HOME=C:\Sun\jwsdp-2.0\apache-ant
ANT_OPTS=-Djava.endorsed.dirs=C:\Sun\jwsdp-2.0\jaxp\lib\endorsed;C:\Sun\jwsdp-2.0\jaxp\lib
JWSDP_HOME=C:\Sun\jwsdp-2.0
PATH= (Added) C:\Sun\jwsdp-2.0\jwsdp-shared\bin; C:\Sun\jwsdp-2.0\jaxb\bin\

Now, I can compile XML schemas from the command line by using the XJC.BAT command. Since I had created a Java project already containing the schema, I needed to use a command prompt to change to that directory and run XJC against the resulting .XSD file created by the Web Tools Project XML Schema designer. In order to do that and create the Java classes, I run the following commands, where C:\WTP is the location of my Eclipse installation, C:\WTP\WORKSPACE is the location of my workspace and project files.

cd c:\WTP\workspace\FileStructureXML
xjc.bat –p com.digiassn.blogspot.filestructure FileStructure.xsd

That’s it, the following files were created from the above commands:
C:\wtp\workspace\FileStructureXML\com\digiassn\blogspot\filestructure\
C:\wtp\workspace\FileStructureXML\com\digiassn\blogspot\filestructure\FilesInFolder.java
C:\wtp\workspace\FileStructureXML\com\digiassn\blogspot\filestructure\Lfile.java
C:\wtp\workspace\FileStructureXML\com\digiassn\blogspot\filestructure\ObjectFactory.java
C:\wtp\workspace\FileStructureXML\com\digiassn\blogspot\filestructure\package-info.java

And next article, I will wrap this up and show the completed application.

Saturday, December 09, 2006

Eclipse: Graphical XML Schema Building using WTP also known as JaxB Article Part 1

While I know I said I was going to have a second article about adding onto my RCP application, but I got sidetracked. My boss got me interested in working with JaxB (Java Architecture for XML Binding) to build Java code to marshal (handle writing to) and unmarshal (reading from) XML files. The basic theory is this, you write an XML schema, run JaxB against said schema, and it will generate the code you need to handle information in said data structure. So, over the next few articles, I will discuss how to do so, which may benefit the RCP application as well as I may incorporate some example of that into the final product to save results or something.

Now, I personally don’t really care to write out tons of ridiculous XML structures by hand. I had read several suggestions, such as using commercial products like XMLSpy, but the best solution was suggested in a conversation with Scott Rosenbaum of the BIRT PMC. His suggestion, why not build the schema using the schema designer in the Eclipse Web Tools Project. Lo and behold, this solution works like a charm.

The idea behind the following example will build off of the Java recursive file system retrieval code I showed in my last article, get relevant information (name, path, size, date last modified) from the local file system (using Windows C:\ as my example), and build an XML data file using JaxB generated code to marshal the building of that file. For this example, I used the Web Tools Project All-in-One distribution of Eclipse, available here. I got that, extracted into a local folder (C:\WTP), and was ready to go.While I could have just installed WTP into my existing Eclipse instance, considering the problems I have had in the past with Eclipse plug-ins, and how the BIRT All-in-One saved me from hours of headaches with the Callisto release, I decided to stick with a formula that works.

The design of my file is like so. I want a key element called LFile, which is built like:

Name : String
Path: String
File_date: Date
Size: long
Read-Only : Boolean
IsDirectory : Boolean
SubFiles: FilesInFolder

On top of that is the structure FilesInFolder, which is basically a List of LFiles. I called my structre Lfile so as to not have to worry about naming convention conflicts between my structure and the java.io.File object.

My first step is to create my Eclipse Project. I open up Eclipse in the Java perspective. I go to File / New /Project, choose new Java project, and follow the wizard. I call my project FileStructureXML. Once my new project is created, I go to File/New/Other/XML/XML Schema. This will create a new XSD document. I called my file FileStructure.XSD. I choose to open my newly created in the XML Schema Editor.

Once open, the XML Schema Editor is a graphical schema design tool, which in my opinion is much easier than writing code by hand. So, the first thing I need to do is create my custom types. I go over to the Types section, Right-mouse click and choose Add Complex Type. I call my new Type Lfile, and add Elements (add elements, not attributes) as indicated above, with the exception of the SubFiles element. Once completed, I save my design, click on the little square in the upper left hand corner of the XML designer to go up to my top-most design, and create a type called FilesInFolder. I create a single element, called Files, and specify the type to be Lfile. In order to do this, I had to select the files element, and in the property editor, choose browse, and select Lfile from the list of types. I hit OK. Back in the editor for the FilesInFolder type, I select the files element. I then specify the min occurance to be 0, and the max to be unbounded. This will create a List of Files when I generate the Java code. Now, I go back to my top most design, select the Lfile type, double-click to go into its, and add an element called subFiles. I specify the type to be Lfile and set the min and max elements appropriately. I go back to my top-most design again, and create a single element called DirectoryStructure and set the type to be FilesInFolder. I probably could have just as easily create an element called RootFile and specified it to be a Sequence of Files, but I always seem to have problems with that. So, although this will generate an extra invocation in my resulting Java class, I will live with the DirectoryStructure element instead. Since this is just a demonstration, this will work just file. I save this as my design schema. Once complete, my resulting XML Schema Design looks like so:


Figure 1. The Schema Designer

And the actual Schemas XML is in Figure 2.


<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/FileStructure" xmlns:tns="http://www.example.org/FileStructure" elementFormDefault="qualified">
<complexType name="Lfile">
<sequence>
<element name="name" type="string"></element>
<element name="size" type="long"></element>
<element name="path" type="string"></element>
<element name="date_last_update" type="date"></element>
<element name="isDirectory" type="boolean"></element>
<element name="readOnly" type="boolean"></element>
<element name="subFiles" type="tns:FilesInFolder"></element>
</sequence>
</complexType>

<complexType name="FilesInFolder">
<sequence>
<element name="files" type="tns:Lfile" minOccurs="0" maxOccurs="unbounded"></element>
</sequence>
</complexType>

<element name="DirectoryStructure" type="tns:FilesInFolder"></element>
</schema>
Figure 2. XML Schema Code

Of course, the above illustrates why having some sort of Class Diagram or high-level design becomes necessary. Especially when the data structures get more complicated, and you are dealing with a system with lots of complex data structures of this type.

Next step will be to generate the Java classes from this schema, which I will discuss in my next article.

Wednesday, December 06, 2006

Java: How to Create a Basic RCP Application

So, at the gentle nudging of my new boss, I have been looking into building applications with RCP. In theory, it seems like a sound framework. In practice, I have run into quite a few pitfalls. Much of it is a major philosophy shift on my part, or rather the difficulty dealing with the Eclipse plug-in paradigm. So, over the next few articles, I will share my experiences in building what I hope is a simple RCP application.

The application I will build here is a simple web service communication program that will use the Google web service to query Google and retrieve the results. I decided to build this application for several reasons. First, it somewhat mirrors the application I am currently building for work, in terms of getting information, using a web service, and using JAR files external to the RCP framework. I will use Apache Axis to generate proxy classes to use with Google. Requirements for this series are Eclipse, Java 5, and Apache Axis. As an added bonus, for no apparent reason, I will also have a Tree List that displays all files in the root of the drive. So in this article, I will demonstrate a few things. First, I will demonstrate how to create an RCP application in Eclipse. I will also demonstrate how to modify a view, add visual components, and I will demonstrate how to retrieve a file list and directory listing in Java, using a recursive function to populate an SWT Tree component.

The first step is to create the RCP project itself. Here are the steps.

First, open Eclipe. Once Eclipse is open, open the Java Perspective. You do this by going up to Window / Open Perspective /Java (Or if Java is not there, go to Other / Java). Now, we need to start a new Plug-in Project. Go to File / New / Project. When the wizard opens up, choose Plug-In Development / Plug-In Project.


Figure 1. New Plug-In project.

On the next screen of the wizard, enter in a project name (in my case, I am naming it com.digiassn.blogspot.RCPTutorial). Make sure the Create a Java Project option is checked, and set the Eclipse version you are targeting. I set mine to version 3.2.

On the next screen, be sure to check the option to create a Rich Client Platform Application. Enter the other parameters (I left mine default). On the next screen there is a series of templates. I chose the RCP Application with a View template. Once done, I just hit Finish, and my initial project has been created.

That’s all there is to it to create an RCP application. Now, I can test run the application by clicking on the Launch an Eclipse Application item in the editors Overview tab, under Testing.


Figure 2. Project Editor


Now, with the new project created, I want to modify it to provide the interface I want to use. Since I used the above template, I can modify the src/com.digiassn.RCPTutorial/View.java file. What I want is to clean up some of the junk that the Eclipse wizard threw in, remove the wizard generated objects in the view since they do not coincide with my goal for this program, and add the necessary components to my view. I also need to put in the code to initialize my TreeView object with my file listing. For run-times sake, I choose to just display a list of directories. In order to do this, I use the Java File object, and create a recursive function that will populate the list for me. The way it works, is it gets a list of files, if the current file is a directory, it creates a new tree item, and then recalls itself using itself as the root value. I was kind of stoked; I haven’t had to write a recursive function since high school. The code for the View.Java file is below.


View.java
package com.digiassn.blogspot.rcptutorial;

//Necessary imports for SWT components
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import java.util.Date;

import java.io.File;

public class View extends ViewPart {
//The tree list displaying files
private Tree treFileList;
//String generated by wizard to identify the component
public static final String ID = "com.digiassn.blogspot.RCPTutorial.view";
private Shell this_shell;

private void populateTargetTree(Tree parent, File root)
{
File []listOfFile = root.listFiles();

//For each of the files, check if it is a directory, and add
//to the tree object
for (File f : listOfFile)
{
//Try statement added. Reason being, if the current file has
//special access permissions, Java does not handle correctly
//and causes a runtime exception and causes a stop in processing
try {
//Check if it is a directory
if (f.isDirectory())
{
//create new tree item, setting the data to the current file for
//later use
TreeItem t = new TreeItem(parent, SWT.NULL);
t.setText(f.getName());
t.setData(f);

//Make a recursive call, populating TreeItem with
//all child directories
populateTargetTree(t, f);
}
} catch (RuntimeException e) {
//Do nothing
}
}
}

/**
* populateTargetTree
*
* @param parent (The Main treeItem)
* @param root (The Root folderr in the file system
*
* A recursive call, similar to the populateSourceTree function, but
* populataes with the local file system instead of the Actuate encyclopedia
*/
private void populateTargetTree(TreeItem parent, File root)
{
File[] listOfFile = root.listFiles();

for (File f : listOfFile)
{
try {
if (f.isDirectory())
{
TreeItem t = new TreeItem(parent, SWT.NULL);
t.setText(f.getName());
t.setData(f);

populateTargetTree(t, f);
}
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
this_shell = parent.getShell();

//Create a group component, this will house the components related to the
//Google portion of the program. Use the veritcle layout Fill for layout management
final Group grpGoogle = new Group(parent, SWT.NONE);
grpGoogle.setText("Google Stuff");
grpGoogle.setLayout(new FillLayout(SWT.VERTICAL));

//Now create the group for the file system component
final Group grpFileSystem = new Group(parent, SWT.NONE);
grpFileSystem.setText("File System");
grpFileSystem.setLayout(new FillLayout(SWT.VERTICAL));

//Add the tree list that will display the files on the hard drive
treFileList = new Tree(grpFileSystem, SWT.BORDER);

//Add a listener to the tree that will display the information about the directory
//stored
treFileList.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
MessageBox m = new MessageBox(this_shell, SWT.OK);
String message_to_display = "File: " + ((File) treFileList.getSelection()[0].getData()).getName() + '\n' +
"Path: " + ((File) treFileList.getSelection()[0].getData()).getPath() + '\n' +
"Last Modified: " + new Date(((File) treFileList.getSelection()[0].getData()).lastModified()).toString() + '\n' +
"Number of Subs: " + String.valueOf(((File) treFileList.getSelection()[0].getData()).list().length);
m.setMessage(message_to_display);
m.setText("File Selected");

m.open();
}
});

this.populateTargetTree(treFileList, new File("C:/"));
}

/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
}
}

Next article I will create the proxy classes for Googles web services, then show how to import them into the project. This can be a problem, as I found, since Eclipse RCP projects require that JAR files be part of a plug-in. I will show a workaround for this.

Having worked with this for a little bit, I can say this had suprisingly a lot of pitfalls. Documentation was incredibly sparse, and I had a lot of difficulty finding solutions to issue, such as the external JAR issue I mentioned. Most answers I found were in news group posts. This, to me, is not good, especially for younger programmers who are learning. Shame on Eclipse for not having better documentation on these kinds of things. While I do like the RCP framework, I think it has a long way to go. I did come across the RCP Developer from Instantiations that provides some better wizards, and a decent visual designer.

Friday, December 01, 2006

Hypeless Launch: Windows Vista

I had absolutely no idea that Windows Vista had launched. Really. With XP it was all press covereage and articles galore. I couldn't turn around without hearing the hype about XP in its media blitz. With Vista, I can hear the crickets chirping. Thats says alot coming from someone who remains pretty much oblivious and desensitized to advertising. In fact, when I did some fact checking for this article, I only found one article on BusinessWeek with a launch date. I was only reminded of its launch by reading an article by Taosecurity. Does anyone even care that Vista has launched?

Saturday, November 25, 2006

Health: After Thanksgiving, Try the "Old Wives Tale" Diet.

Well, I had hoped to hold off on this article until after the first of the year, but since it’s just past the Thanksgiving holiday, I figured now is just as good as a time as then. So, you’ve stuffed your face over Thanksgiving, and now you want to lose a little weight. Well, let me fill you in on the secret to weight lose.

EXERCISE, EXERCISE, EXERCISE!!!!

This is based on my own personal experience. At the beginning of this year, I made the old New Years resolution to lose weight. Now I didn’t want this to be just the old make a resolution and forget about it. Here I was, sitting at 270 pounds, a lot more than I wanted to weigh.

I did tons of research, looked at tons of diets, and listened to a lot of non-sense. And you know what I found? All of those people are full of crap. There is no magic diet, no wonderfully easy way to lose weight in a healthy manner. I say healthy, because all off these diets have one thing in common, you cut something out. It can be carbs, fats, calories, whatever and it isn't healthy. I realized one thing that was common to all of them that I found to be a truism, cut out sugary foods, like donuts, candy, and sodas (for me, sodas were the big one). So what I put together was a combination of themes that I used for my diet. Here I am now, sitting at 220 pounds. That’s after the Thanksgiving break, after I stuffed my face, and I didn’t gain a pound.

So, what is this ingenious “diet” I put together. It’s not so much a diet as a series of guidelines I call the "Old Wives Tale" Diet. Why? As I said above, it's just like we have always been told, eat less, exercise more. Let me start with the eating portion, since it is the easiest part to discuss. First off, people are fickle. We like our tasty foods. The problem with people, especially Americans as any European who has visited this country will tell you, is that we eat entirely too much food. Our servings are insanely large. Sickeningly so. I hear this complaint from foreigners, and I look at the obesity in this country, and I can’t believe that other people haven’t figured this out as the single “biggest” cause of the problem. So, guideline 1, eat half of what is served to you. Deny that urge to finish the plate. Think of it this way, your 6-dollar McDonalds hamburger can be two meals instead of one. You then get to have McDonalds twice in a day. So take that Big Mac, and cut it in half. For me, it was doing things like ordering a single instead of a double. Over time, my appetite subsided, and I could only eat that single, then it got to only half the burger, then half the burger with no fries. YMMV.

Second, I came from a strange household where I picked up a strange eating habit of devouring my food in record time. I am not sure if it is the military lineage that my father, grandfather, and uncles have, and I picked it up there (note, the military bug skipped a generation). Or the rush to get back to the TV/PC, but I eat fast. As a result, when I ate, I was still hungry. It has been said that it takes 20 minutes for your brain to register that you are full. So guideline 2, eat slowly. If you have to chew your food 72 times (isn’t that the number they always recommend) or whatever, do it. Take 20 minutes to eat that half a burger. You might as well savor the flavor and enjoy your food while you got it.

Now, after a few months of this, came a problem. I stopped eating meals altogether. First it went down to 2 meals a day, then 1, and then every other day. I realized this was not health in the least bit. Plus, I stopped losing weight, and would either flat line or start gaining. So, after a little research, I came up with a solution. I started to supplement my meals with 2 things. First, I forced myself back into eating a breakfast. Now, I didn’t just eat any old breakfast, I turned to the Gracie Diet for help. The Gracie Diet is not a scientifically proven diet, but is a diet that has had wonderful results for the Gracie family. If you don’t know who the Gracie’s are, turn on the UFC one day; you will hear them mentioned at least once. Or just go to your local video store and rent the first few UFC’s. You will get an idea. To put it into perspective, the Gracie diet is one that this family of fighters, who have basically invented the modern sport of cage fighting and modern Brazilian Jiu-Jitsu, have lived by. Their eldest member, Helio, is over 90 years old and still goes strong. That’s a 90+ year old man that could whoop just about anyones butt. How’s that for healthy. It is a certain combination of fruits, vegetables, and other groups in a way that they have felt aids in digestion and gives them energy. Not so much what you eat, but how you combine them. So, this became my breakfast. I picked about 4 different recipes that I liked and are easy enough to make as my breakfast repertoire. These are as follows:

1: Apples and Bananas

Take 4-5 apples, core them, and juice them. Apples corers are about 1 buck at the grocery store, and most nowadays have a slice built in, so you can slice and core at the same time. Take 3-4 bananas put into a blender with the apple juice, mix and drink. The Gracie’s say you can mix ice cubes and crème cheese, but I don’t care for crème cheese. Do not use apple juice from a container, as it contains preservatives, and it loses vitamins. Even ones labeled “No preservatives”. We live in a wonderful country where fruit is already picked and delivered to the store for us. All you need to do is wash it. The Gracie’s handpicked theirs in Brazil (I doubt the ones living in the US pick their own anymore), so be thankful).

2: Bananas and Milk

Take 3-4 bananas, put into a blender, put in milk (I eyeball this, leaving the bananas whole and put enough milk to where ¾ of the bananas are covered), blend and drink. This one is my favorite since it is the quickest, easiest to clean up, and has the best taste.

3: Grape juice

Take ½ pound – 1 pound of sweet grapes. Blend; run through a strainer, and drink. This is probably the hardest one to drink. Grapes taste great individually, but they are hard to swallow like this. One of the things behind the Gracie diet though is we are too stuck on what tastes good, and need to get over it in favor of what’s healthier for us.

4: Fresh Orange Juice

Take about 4-5 oranges, juice them, strain to remove the pulp and drink. This is another one of my favorites. But I have found freshly squeezed orange juice does not taste the same as the kind you buy in the store, leading me to believe there is a lot of additives in the store bought one.

One thing to note, I eat each one of these with a multi-vitamin, every day. There are other recipes, such as carrot juice, that are good also. But, since I do most of my “on the move” eating in the afternoon and evening, this breakfast fits in perfectly. When my fiancée was away, this diet was great because I could eat two meals in this fashion, and saved a nice big dinner for her and me. Other diets say eat this type of food, or that, but as I have found, we just eat anything for dinner in smaller portions and it works out fine.

Now, as Ii mentioned before, the secret isn’t the dietary part. The secret is, as our mothers have ALWAYS told us, is exercise, exercise, exercise. My mother is smarter than the whole league of scientists, dietitians, and all these other witch doctors because this is where I have ALWAYS seen the most consistent weight lose in just about anyone I know who does it. As my mother always told me, “Get off your ass and exercise”. Diet alone will never be enough. You may see some initial loses, but you will plateau and not lose a pound more if you don’t exercise.

So what is exercise? This is another one of those guideline things. For me, exercise was any number of things:

1: At least 3 times a week

2: 20 Minutes of hard-core cardio

3: Something fun

Fun differs between people. For me, it is Kenpo Karate and Brazillian Jiu-Jitsu, coupled with bike riding, running with my Ipod, and jump roping. For my fiancée, it is dancing, tennis, and soccer. Being Latin American, she lives and breaths soccer, being that I am from the United States, I couldn’t care less. But fun is fun from certain perspectives. Point is, go out and do something you love. The most important thing is to keep yourself entertained. I use my Ipod, or I take someone with me when I workout. I love the martial arts since it’s a group activity and it helps keep me motivated.

My regiment usually consists of:

1: 10-15 minutes of stretching. Take 10-15 seconds per muscle group. Always warm up each muscle before you stretch by shaking it, or some light workout.

2: Simple stuff: 3 sets of sit ups with a medicine ball, 3 sets of push ups, and 5 minutes of Jump roping.

3: 45 mins – hour of Kenpo. I do all the forms, sets, and techniques in the Kenpo system. Although of late I haven’t been attending class so much, this still keeps the techniques and stuff fresh. Sometimes I perform on a bag when available.

3: 20 Mins of running: This I typically do on an elliptical machine to save wear and tear on the knees. I do a particular series where I run real hard for a minute straight, job for 2 mins, and repeat, up until 13 mins, where I jog for the remaining time.

4: (optional) Bag work: Here, I will do punching and kicking drills on a standup bag, or will work on ground and pound drills on a bag on the floor. I used to have a partner for this, now I don’t.

5: Extracurricular Activities: As mentioned above, I do Kenpo and Jui-Jitsu in the evenings. This is separate from my daytime workout. I also try to golf on the weekend, or ride my bicycle. The bike trip I take is a 20 mile ride to my former place of employment since it is on a nice, isolated stretch of road, and since this is Texas, our version of winter is about 60 degrees, so its always in season.

Exercise is the key ingredient here. In all the times that I have slipped off the dietary part of my weight loss program, the exercise has kept me from ballooning up. The fact of the matter is we are people, and people have things that come up. Parties, weddings, funerals, birthdays, holidays, special events of all sorts. Just because your trying to lose weight, doesn’t mean you can’t enjoy these events. I tried turning down things like cake at parties, but that just gets you funny looks. So a slice every now and then isn’t the end of the world. I didn’t die from massive coronary shock or balloon up from slipping every now and then, I just had to keep consistent with my exercise and get back on track. In this day and age, you can Tivo your favorite shows, or better yet, get them on your Ipod and watch them while your on the treadmill, that way you don’t feel the “imaginary” obligation to be at home for your favorite show. When I still worked in an office, I took my lunch hour to work out at the company gym, and ate soups for lunch. Point is, they key here is the burning of energy, that’s how you’re going to lose weight.

I don’t weight lift, at least not reguarly. For one, weight lifting grows muscle, and I am trying to get smaller. You can get toned, and work certain problem areas (backside, stomach). Consult someone who knows to find the best exercise to work those problem areas. If you’re a man, you have what I refer to as the hero complex. Brad Pitt said it best in Fight Club, so I don’t need to repeat it. You have the body that was given to you, so improve it, don’t try to have someone elses body. Which brings me to point two, most people do not weight lift correctly. I see a lot of guys at the gyms lifting ridiculous weights, which almost always casuses me to laugh. First off, most guys do the quick jerk weight lifting, which is neither health, nor beneficial. This builds what I call “paper muscles”. Proper weight lifting comes from slow, even movements with resitence on the give as well as the take. You can get a lot more from lower weight this way than from the grunt and shove method. Case in point, there was a guy Dave who worked out this way. He was a model that we knew. One day we went to go pick up a TV from his house so we could fix it. Here are two guys, me and my buddy, who did this every day. Dave helped the two of us, and the comedy ensued. The guy couldn’t carry his own weight, despite his “big model muscles”. He cried like a little girl, had to stop every few feet. It was almost like we were better off without his help. A few weeks later I saw him working out at the gym. Here he is lifting weights, using the quick jerk method for bench pressing, and using the swinging assists for arm curls. He was more focused on the numbers on the side of the weights than actually building any sort of strength or muscular endurance. Just because you lift it in the gym, doesn’t mean it will do you any good in reality. So if you lift, lift with a goal in mind. Tone, muscular endurance, and strength are not necessarily mutually inclusive. I have met butchers and auto mechanics with more “strength” than these phony muscle men, so don’t believe the hype. The reason being, these guys work against a resistence consistently, every day, using the same muscles. That’s why auto mechanics have the handshake of death.

So to summarize:

1. Eat less, exercise more

2. Eat smaller portions. Work your way down until you’re at a portion you can eat and be full. This way you eat what you like.

3. Eat slower

4. Exercise at least 3 times a week, for at least 20 minutes (I recommend an hour). Find something you like (Basketball, racquetball, soccer, tennis, martial arts, bike riding, running) and get out there and do it.

5. Have a goal in mind, and keep it reasonable. For me, it was 230 pounds by the end of the year. I have exceeded that goal. Next year, I will shoot for 200 by the end of the year.

6. It takes time, so be patient. You may not see results immediately, or you may see rapid results that taper off over time. In the first few months, I lost 30 pounds rapidly. I’ve fought real hard to lose that additional 20 pounds to where I am at today. And that given all the slip ups.


In all of this, I don't have any "scientific" evidence, any expert claims, or any other such nonsense. I have the 50 pound that I have lost, the the surprise of my doctor that my once high numbers in blood tests have dropped to exceptionally normal thresholds. I'm not here to convince you to send me money for the secret to weight lose, nor will you see me with annoying spam or pop-up messages with my ultimate secret. It is just like our parents always told us, go out and exercise, and drop that dang donut. It's a hard road to follow, so be sure you are willing to make the comitment.

Monday, November 20, 2006

BIRT: GDI Error Using the Chart Engine

After starting up BIRT and trying to do some work with the Chart Engine, I kept getting an error saying “Unable to load graphics library [GDI+ is required]”. In order to fix this, I downloaded the GDI+ SDK Redist package from Microsoft, and extracted the files into my Eclipse installation folder (the folder containing Eclipse.exe). After that, Eclipse worked like a charm.

Oracle: Generating Random Numbers

In generating a large set of test data for report development, I had needed to populate a columns data with random numbers between a given range. Fortunately, Oracle provides this in the form of its DBMS_RANDOM package.

For my case, I needed to set a foreign keys value to anything within a range of values in another table. I know that my range in this other table is 1-100, so to update my table with those values, I would run something like:

Update mytable set myfield = trunc(DBMS_RANDOM.VALUE(1, 100))

The trunc became necessary since Oracle was spitting out values with decimals.

BIRT: Getting URL Parameters to Work in Reports

A question was asked about being able to pass in values from a URL, and have it do something in the report. In order to get this to work, all you need to do is create a report parameter. So, using my previous report example here, I can send a value to the rptparamCheckBox1 parameter through the URL as a URL parameter. So if I deployed my example report linked above, to an Apache BIRT Viewer instance at 127.0.0.1, I would call it with the following URL:

http://127.0.0.1:8080/birt/frameset?__report=CheckBoxReport.rptdesign&rptparamCheckBox1=false

Now, I can change the URL and have it show up in the report. This will also work with hidden parameters that you may want to use to affect layouts. So, if I add a Highlight, as indicated in Figure 1, I can have the text show up as red when the value of rptparamCheckBox1 is true.


Figure 1. Highlight Based on Parameter.

Sunday, November 19, 2006

BIRT: Making a Checkbox Parameter

A question came up about making a BIRT report parameter as a check box. The process is pretty simple, so let me walk through it. I will go through this from the ground up. The project I am building will not need to use any data sources since it will simply display the result of the parameter itself.

First, I open up the Eclipse IDE. I switch over to the BIRT perspective by going up to Window/Open Perspective/Report Design. I create a new BIRT project, and call it CheckBoxParameterReport. Once this project is created, I go to the Project Explorer, right mouse click, and select New Report. I call this new report CheckBoxReport.rptdesign. I create this as a Blank Report.

Once the newly created report is open in the designer, I open up the Data Explorer tab. Under this tab, I right-mouse click on the Report Parameters section, and selet Report Parameter. In the report parameter dialog, I fill in the values as outlined in Figure 1. Be sure to change the type to Boolean, otherwise the correct prompt types will not be displayed.


Figure 1. Report Parameter Dialog

Once filled in, I hit OK, drag the parameter over to the design window. I save the document, go over to the project Navigator, then right-mouse click the report design, and choose Report/Run. I then get greeted with the Parameter Dialog with my check box, once I click my value and hit OK, I get the report showing my selected value.


Figure 2.
My Dialog Box

Monday, November 13, 2006

Charity: Childs Play 2006

While I typically try not to push certain views out, I really feel that I should try to do “something” to get the word out about the Childs Play charity. You see, I feel somewhat that I should try to do more to make a push, and this particular charity pulls at my heart strings for some reason. Last year I got my gaming site to put together a pool where they sent out a little bit of cash. This year, I figured I would plug it on the here as well.

For those who aren’t in the know, Child’s Play is a charity put on by the good folks over at Penny Arcade. The philosophy behind this is that sick, hospitalized children can have less recovery effort if they are entertained, thus getting their mind slightly off their afflictions. So Child’s Play puts all of its proceeds towards toys and video games for sick children that are hospitalized. They donate ALL, that’s 100%, of the funds they raise, in addition to any charitable gifts to the hospitals participating.

Besides the charitable donations, they also currently have a series of auctions going on over at EBay, which include a number of original sketches of their artwork. Being the fan that I am, I wish I had enough to buy one of these. Not only for the memorabilia, but the thought of the money going towards a good cause.

Something about this really gets me, so I feel this is one of the most worthwhile charities I think I have ever heard of. While most take a portion for administrative costs, Child's Play puts 100% towards the children. I'll definitly be making more of a push this year to get the word out and put a contribution in myself.

Sunday, November 12, 2006

Rant: Hawking Broadband Booster Blocking Inbound Connections

Now this is very strange...

I have a Hawking HBB1 Broadband Booster in my network to help with my online gaming. I love this device, ever since I put it on my network, I "appear" to have absolutly no lag whenever I play games online through my XBox, XBox 360, or PC games.

Now here comes the problem... since I recently consolidated all my olders PC's (which, since moving into my new apartment, have been out of service) on to my server under VMWare, I cannot establish connections from outside my LAN. I troubleshot this issue to death, and determined only 2 things have changed since the last time this worked. First, the PC's were moved into VMWare. Second, the Broadband Booster was added between the Cable Modem and the Router. And wouldn't you know it, if I remove the Broadband Booster from the network, I can connect no problem.

Now this is a little strange. I've had some quirky issues with the Broadband Booster in the past. I've had choppy network connections, intermittent Open status NAT connections using XBox live, and a few other quirks. Almost all of these were corrected with either a little configuration, or a firmware update. Now the Broadband Booster is supposed to be a passive device, it does not act as a NAT device in any way, it only monitors traffic, and adjusts QoS based on what it sees.

So if that is the case, why the hell is it blocking inbound SSH traffic? I suppose in the mean time I will have to remove this little device when not in use, but thats kind of a hassle.

Wednesday, November 08, 2006

VB: Start and Stop Macro Execution with a Button Click

I recently had someone ask me if there was a way, in VB, to start and stop a series of sub routines from running. The problem with Visual Basic is the lack of any sort of easy to use multi-threading. There are a couple of solutions however, while not exactly the prettiest, will do the job. The topic of multi-threading is a very complex one, so we will keep this simple and stay outside of that realm.

The first solution is to use a Timer component as the driver for your subroutines. You can then start and stop the timer at your leisure.

The second is to have a series of flags determining the state of the subroutine runs, run the subroutines in a loop, and use a DoEvents call so the program is not in a locked state.

For example, lets say I have an Excel spreadsheet that runs a series of functions in a loop. I want to be able to start and stop that with the click of a button. I would use something like the below, where UserForm1 is my containing my buttons, CommandButton1 starts my loop, CommandButton2 will show my the status of the loop in a message box and ask me if I want to stop, and TextBox1 will show if the loop is running. The loop in the example will only increment a counter X by 1, and reset it if it gets over 6,000,000.

Option Explicit

Dim x As Long
Dim continuerun As Boolean

Private Sub CommandButton1_Click()
continuerun = True
While continuerun
x = x + 1

If x > 6000000 Then
x = 0
End If
DoEvents
TextBox1.Text = continuerun
Wend
End Sub

Private Sub CommandButton2_Click()
MsgBox x
continuerun = (MsgBox("Continue running loop?", vbYesNo) = vbYes)
TextBox1.Text = continuerun
End Sub

Of course, the third option, since it would be in a macro, is to keep the DoEvents call in the loop, and just go into the VBEditor and hit escape or the stop execution button.

Monday, November 06, 2006

Recreation: Playing with the Wacom Drawing Tablet

Ever since I read Mike Krahulik (Gabe of Penny Arcade) article on his inking of a Boba Fett sketch he did, I’ve been bitten by a little artistic muse, which has quickly grown to a nagging infection in my mind. Being the big fan that I am, and since I always wondered how hard it would be to do the same thing, I decided to mimic his actions. I got in touch with a friend of mine who is a local artist, and who happens to have a Wacom tablet of her own, and convinced her to let me try this myself.

The Intuos2 6x8 tablet that she has is a pretty cool little device. It is a pressure sensitive drawing tablet that hooks into a PC or Macs USB port. With a few driver installations, the thing works with Photoshop to provide artists the ability to use a more natural feeling peripheral for drawing and photo re-touching. All and all a very cool little device.

In my case, I stole “Gabes” sketch since I don’t have any artistic talent of my own, and tried my hand at inking it using the tablet. It takes a little hand-eye coordination to get the cursor to go exactly where you want, and it takes a little practice getting the pressure right to you can create variable line sizes. In my case, I had jittery hands when I was trying to draw with it (which is visible in some of the jittery lines), which I am not sure to attribute to the small desk, the tablet size, or my own physical limitations. But once I got moving with it, I was able to follow along with his YouTube video fairly well. While he claims the overall process took him about 15 minutes, it took me the better part of an hour, maybe an hour and a half. The cool thing about this as opposed to the paper method of inking is it is incredibly easy to undo once you make a mistake, which in my case was quite often.

Anyway, here are my results, please be kind:


I don’t think I will be quitting my day job anytime soon, but it was enough to satisfy my curiosity. I have a new respect for not just for the Penny Arcade guys, but for artists in general. It’s one of those things, if it was easy, every fool would do it.

Friday, November 03, 2006

Windows: Running Scheduled Tasks Manually from the Command Line

I ran into an issue on a Windows XP system where the RUN command for all Scheduled Tasks was disabled and grayed out. I needed to manually run one of my scheduled tasks, and could not do it. I am not sure if this is due to domain/local policies or registry trickery, but regardless I found a way around it. Microsoft included a neat little utility called SCHTASKS.exe under the C:\Winnt\System32 folder that will allow a user to control Scheduled Tasks from the command line. I had a task called CESL that I wanted to run, so to run that task, I ran the following command:

C:\winnt\system32\schtasks.exe /run /tn CESL

That took care of my problem.

Monday, October 30, 2006

Rant: The IDS is Dead, So Lets Throw the Baby Out with the Bathwater!!

Taosecurity is fighting the good fight. I am just shaking my head since I have long given up on the security community as a whole due to short sightedness and egotism. My perceived problem with the security community is that they want some magic “Silver Bullet” that will cure all of their woes so they can kick their feet up on the desk and not have to do any real work. So if one tool doesn’t work, they just want to chuck it to the curb with their old servers.

Taosecurity hits at the nerve of the issue in pointing out the difference between “product” and “system”. The “IDS” is typically seen as things like Snort, which is a product by Rich definition. I prefer the term tool myself, since it gets at the point I always try to make, whether its security, programming, or making a peanut butter and jelly sandwich. You need the “Right tool for the job”. In addressing the problem of security, the IDS is just another tool, and you need a whole bunch of tools to solve a problem of that scope. And just like any other tool, you can improve and modify it, like say combining the firewall and IDS to try to create an IPS, but it is not going to fully replace the two separate tools any more than the Nail Gun has replaced the good ‘ole hammer in the field of carpentry. (Which draws an interesting parallel, why don’t we see carpenters making such bold claims like “The Hammer is dead” while championing the Nail Gun? It’s probably because the hammer is still the appropriate tool for the job in a given set of circumstances.) Every few months someone’s got to go around with claims like “The IDS is DEAD”, or “The Firewall won’t protect you forever”, and silly one size fits all solutions like “Smart Firewalls”, “IPS”, and whatnot and what have you come around. I’ll believe the IDS is dead when claims like C/C++/Java/Whatever dies as well.

That whole “Right Tool for the Job” concept is a hard one for security theorist to grasp, and provides a decent lead in to a rant I’ve wanted to get off my chest. To demonstrate this, I recently had a discussion with someone in the security community the other day about a series of reports I am building in BIRT. The security guy basically tried to make an argument that the same thing could be done in PERL since it is already on the system, and reduce the need to install any further software. His real hidden agenda was to take an undeserved dig at Java as a language, and Java tools. Having developed reports in PERL before, I can easily say yes, it is possible to build these reports in PERL, but the guy is off his rocker if he thinks I am actually going to do so based on his opinion any more than I would be if I had entertained the notion of trying to convince him of my point of view.

From my perspective, it simply is not the appropriate tool for the job for a number of reasons. First, BIRT is a platform dedicated to reporting, PERL is a general purpose scripting language. Second, it is much easier to maintain a reporting system in BIRT than it would be in PERL due to the reduced amount of coding. And Third, it leverages the concept of re-use, so I can apply the combined knowledge of developers who have come before me and built a system of reporting elements in an easy, flexible, and rapid development method without having to rediscover the pitfalls that they discovered. After all, a whole community building a dedicated tool would know a little more than little ‘ole me trying to develop something from the ground up, hence BIRT reason for existence and following by a dedicated developer community. So on the merits of scope, maintenance, re-use, and development time, BIRT was determined to be the appropriate tool for the job.

This is an attitude I encounter all too often. While some would consider it cockiness or outright rudeness, I actually believe it’s more of a reflection of fear. To use an analogy, they would prefer to lock the house in a vault rather than risk it being broken into, regardless of the fact that the airlessness of the vault will kill everyone inside.I could go much deeper, but that touches on another one of my beliefs of the failing of the security community, their lack of perspective in the concept of utility. While I agree that security should not be sacrificed in terms of security, I do not hold the seemingly overwhelming belief in over-securing an environment to the extreme of limiting the utility of a system to the point where it is totally unusable. I have seen this trend prevail all too often, and does not address the real issues of security, or lack there of, in an environment. All it does is limit users while giving security teams a sense of accomplishment, meanwhile the real threats are holding the keys to the kingdom.

Point is, there are proper tools for certain jobs, and tossing out Snort because someone claims IDS is dead is doing to leave you as limited as tossing out the Philips head screwdriver when some nut claims that Torx is the future.

Thursday, October 26, 2006

BIRT: Scripted Data Source to Call a Web Service

One of the things that makes BIRT a powerful platform is its how extendable it is due to the ability to invoke Java classes. In the case of the following example, I can report off of the previously developed Web Service using Apache Axis (or more specifically, the WSDL2JAVA utility), a Java class, and a scripted data source.

The first thing I need to do is create the proxy classes using Apache Axis. I used Axis 1.4 for this example since 1.2 seemed to create classes that I couldn’t develop against using Java 1.5. The web service resides at http://my.web.server/test/WS/getEmployeeTranscript/Service1.asmx, and since it is a .Net web service, I will need to pull the WSDL by calling http://my.web.server/test/WS/getEmployeeTranscript/Service1.asmx?WSDL. In order to generate the proxy classes using Axis, I had to call WSDL through Java to generate the WSDL file. Although not necessary, I included all of the JAR files under the <Axis Folder>/lib. So to create my classes, I run the following command:

java -classpath "C:\apache_axis\axis-1_4\lib\axis-ant.jar;C:\apache_axis\axis-1_4\lib\axis.jar;C:\apache_axis\axis-1_4\lib\commons-discovery-0.2.jar;C:\apache_axis\axis-1_4\lib\commons-logging-1.0.4.jar;C:\apache_axis\axis-1_4\lib\jaxrpc.jar;C:\apache_axis\axis-1_4\lib\log4j-1.2.8.jar;C:\apache_axis\axis-1_4\lib\saaj.jar;C:\apache_axis\axis-1_4\lib\wsdl4j-1.5.1.jar" org.apache.axis.wsdl.WSDL2Java http://my.web.server/test/WS/getEmployeeTranscript/Service1.asmx?WSDL

A pretty long command, a batch file or something will help in future uses. I have seen wrappers for this before, but apparently Apache did away with including one in the distribution in a previous version. Anyway, I get a set of classes creating in the namespace structure of my Web Service.

Now that I have these, I need to create a small class to handle my calls. The reason I do this is for logical reasons. Techincally, I could just import these proxy classes and invoke them directly from BIRT, however, I don’t feel that they logically make sense. In my mind, I have a process like so invisioned:

Invoke class with Employee ID ( Assign Data Set values the property values of my Class.

That simple, I don’t want to deal with the issues of calling the Locator class generated from Axis inside of BIRT. So I will create a very simple Java class that will call the web service in its constructor method, and have get methods to return the employees name, ID, and transcript information.

The class I create was done in Eclipse, including my generated Axis classes in the buildpath. It is as follows:

//I have no idea how the java.* and javax.* classes got imported??
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import my.webservice.namespace.*;

public class pojoTest {
//Local variables to store the returned information
private String name;
private String geid;
private TranscriptEntry[] trans;

//The constructor, which will invoke the web service on invokation
public pojoTest(String id)
{
//Get the locator class for my web service
GetEmployeeTranscriptLocator getEmp = new GetEmployeeTranscriptLocator();

try {
//Create the employee object, and assign the variables the results
Employee emp = getEmp.getGetEmployeeTranscriptSoap().getEmployeeAndTranscript(id);
geid = emp.getID();
name = emp.getName();
trans = emp.getTranscript();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//My get methods for my properties
public String getName()
{
return name;
}

public String getID()
{
return geid;
}

public TranscriptEntry[] getTranscript()
{
return trans;
}

//Main will test the class from the command line
public static void main(String[] args) {
// TODO Auto-generated method stub
pojoTest p = new pojoTest("0005003335");

System.out.println(p.getID() + " - " + p.getName());
for (int x = 0; x &lt; p.getTranscript().length; x++)
System.out.print(p.getTranscript()[x].getCourseCode() + " - " + p.getTranscript()[x].getCourseName() + '\n');
p = null;

}

}


I do a test run and check my console output to verify that the web service is being called correctly. Once I am satisfied, I gather up the Axis JAR files, and my .CLASS file for my created class. Now, I read this article on BIRTWorld which seemed to indicate that I could just keep the class file in my project directory and have this work. I will be perfectly honest, I was not able to get that to work. I will have to ask Scott next time I talk to him how he got that to work. What I ended up having to do is follow the steps from here. (Sorry, apparently Actuate doesn’t believe in Anchor tags, so just look for the question “Q: How do I get data from a POJO (Plain Old Java Object)? “). I copied my compiled .CLASS file, my Apache Axis JAR files, and the proxy classes (keeping the same namespace) into a folder under the following path:

C:\Eclipse\eclipse\plugins\org.eclipse.birt.report.viewer_<version>\birt\WEB-INF\classes

Now, since this is all set up for previewing, I need to create a report that consumes this as a scripted data source. In the BIRT Perspective, I create a new report project, called pojoTest. To create the scripted data source, first, go to the Data Sources slot in either the Data Explorer or in the Outline, right mouse click, and choose New Data Source. In the Wizard, choose “Scripted Data Source” and give it a name.

Now, as an aside, I am not sure that the Scripted Data Source is really “doing” anything behind the scenes, I am visualizing that it is just a placeholder, and empty object that fufills the requirement of a dataset that it must have a data source. I could be wrong about that, however I haven’t seen anything that would lead me to believe otherwise, but once I accepted this, I was able to wrap my head around the process much easier.

With the data source created, I go to the Data Sets slot, right mouse click on it, and create a new Data Set. Most of the information is already filled in, I just change the name of the data set to something more meaningful. It is already set to the scripted data source. The columns I created for my data set are as follows:

ID
Name
CourseCode
CourseName

With the data set selected, change to the Script tab in the Report Designer, and select the Open method for the Data Set. To get the scripted data set to call the object, I used the following code in the Open Method:

obj = Packages.pojoTest("0005003335");
transcript = obj.getTranscript();
cnt = 0;
max_cnt = transcript.length;

Here, the class I created is being called via the Packages.pojoTest call. I then pull the transcript into a separate object. The cnt variable is being used in the fetch method as a placeholder to determine which record we are currently on, and the max_cnt will be used to loop through each transcript entry.

Now, the Fetch method itself, where our data set returns a row, will keep being called until it returns false. So, what I do is keep incrementing cnt, set the values of my row, and return true. If cnt > max_cnt, then return false. The Fetch method is below:

if (cnt < max_cnt)
{
row["ID"] = obj.getID();
row["Name"] = obj.getName();
row["CourseCode"] = transcript[cnt].getCourseCode();
row["CourseName"] = transcript[cnt].getCourseName();
cnt++;

return true;
}
else
return false;

Now I can use the data set like a regular query data set. I create a table element in my report, and run the report. It works like butter.

Wednesday, October 25, 2006

VMWare: Server Consolidation Using VMWare

I always go on about the virtues of VMWare. While I think it’s cool as hell that I can run different OS on a single computer, it finally dawned on me that I can use it for one of its intended purposes, server consolidation.

I had a network layout like so where I had several older, smaller PC’s serving a single purpose scattered throughout my network. This can get to be a headache to manage, not to mention expensive on the old electricity bill. Fortune has smiled on me, however, since I happened to have acquired a beefier Dell Poweredge server some time ago. While it is antiquated by today’s standards, it will work nicely in consolidating all these little floating PC’s I had doing menial tasks such as SSH serving and Squid proxying.

Using the free VMWare Server release, consolidating couldn’t be any easier. Simply set up a VM for whatever machine you choose, and either image that VM from the existing machine, or setup a fresh instance and migrate data/processes over. In my case, I chose the latter due to some goofiness with the existing setups and some broken package upgrades (not too bad considering some of these machines have been running processes for several years, and have gone through a few major distro upgrades).

Once setup, the VM instance can be set to startup when the host machine starts up by setting the startup option under the VM settings, Option Tab, and Startup/Shutdown option. That’s it.

Well, that’s not exactly it; I did run into 1 serious problem. Apparently the VMWare Registration Service kept failing to start. When I checked the Event Log, I would see the following error:

The VMware Registration Service service depends on the VMware Authorization Service service which failed to start because of the following error:
After starting, the service hung in a start-pending state.

What the hell is this? After some searching, and not finding any real applicable suggestions, I did manage to come across a decent solution on the VMWare forums (sorry, I don’t have the exact post). Basically, if you set the VMWare Authorization Service and the VMWare Registration Service to manual startup, you can set a scheduled task like below to run on System Startup. This corrected the issue for me. The actual Schedule Task Run command is as follows:

cmd /k "ping -n 61 localhost & net.exe start "vmware registration service""

Now, I have the Virtual Machine running under the 1 server, avoiding the need to have several machines scattered around my domicile. It definitely cuts down on the amount of heat generated, however the server itself is pretty loud. But, I can’t complain, maintenance is much easier now, and if you’re in the same boat, a decent server can be had on E-Bay for under a grand.

Thursday, October 19, 2006

General: Finally Found Code Formatters for Blogger

I finally found a decent formatter for code. As you might have noticed, the code on my site has been hit or miss, due to the irregularities of Blogger for Word, and Blogger in general.

Microsoft Language Specific Formatter

General Formatter

Visual Basic: How to Use ADO to Query Against a Text File

As I continue to migrate scripts over to other people for my inevitable departure from my current job, I am moving over old Visual Basic programs to VBScript for easier maintenance. One of the scripts that I am converting is a small one that gets a list of employees, and replaces their Employee ID’s with their SSN. Since, legally, we cannot store SSN information in our database, we only have a small window to grab the list of SSN’s from an encrypted file, decrypt it, and do the swaps, delete the feed, and send off the encrypted results to our vendor.

The script I have here demonstrates how to do the swap. It will query the parent database to get the list of employees, and then query a Text File using ADO. To speed things up, it only runs the query against the SSN file 1 time, and then pulls finds the results using the RecordSet.Find method. As I explaining yesterday, this is faster than having to do a repetitive query, and in this case, the performance gain is warranted. The only thing I kick myself on is I should have created a function for formatting those darn date variables.

There are a few caveats in querying a text file. First, you need the proper Connection string. I tried a few different things to get this to work right. The ODBC way kept giving me errors, so I abandoned it. I ended up with the following Connection String:

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TEMP\;Extended Properties="text;HDR=NO;FMT=Delimited"

First, the Data Source points to the directory where the files reside, in my case TEMP. In the extended properties, I am specifying that there is no header row, and the format is delimited. The key to get this to work correctly and recognize fields is in a file that must reside in the same folder as the text files called schema.ini. My ssn.txt file looks like so:

GEID;SSN;FirstName;MiddleName;LastName

As you can see, I have semi-colon delimited fields. In order for this to work, my Schema.ini file looks like so:

[SSN_GEID.txt]
Format = Delimited(;)
Col1=GEID Text
Col2=SSN Text
Col3=FNAME Text
Col4=MNAME Text
Col5=LNAME Text

That’s it. I can now query against this text file from within my script just like it was a database. Below is the final script:


Const GETSSN = "SELECT * From ssn.txt"

Const GETEMPS = "Query to get List of employees"

'Variable for output file, usinga temp variab:wle instead of a constant since we need to use todays
'date in the name
Dim OUTPUTFILE_LOCATION
Dim objFSO
Dim objStream

'The ADO objects for retrieving the data we need for employees
Dim adEmpsConnection
set adEmpsConnection = createobject("ADODB.Connection")
Dim adEmpsCommand
set adEmpsCommand = createobject("ADODB.Command")
Dim adEmpsRS

'ADO for getting SSN
Dim adSSNConnection
set adSSNConnection = createobject("ADODB.Connection")
Dim adSSNCommand
set adSSNCommand = createobject("ADODB.Command")
Dim adSSNRS

'X is a temporary counter, plus a few variables to store the numeric day and month
Dim x
dim numericMonth
dim numericDay

'set up the Employees connection
adEmpsConnection.ConnectionString = "Provider=MSDAORA.1;Password=password;User ID=user;Data Source=tserve;Persist Security Info=True"
adEmpsConnection.CursorLocation = 3
adEmpsConnection.Open

'set up the employees command
adEmpsCommand.CommandType = 1
adEmpsCommand.CommandText = GETEMPS
adEmpsCommand.ActiveConnection = adEmpsConnection

'set up the SSN connection
adSSNConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TEMP\;Extended Properties=""text;HDR=NO;FMT=Delimited"""
adSSNConnection.CursorLocation = 3
adSSNConnection.Open

'set up the SSN command for a prepared query
adSSNCommand.CommandType = 1
adSSNCommand.CommandText = GETSSN
adSSNCommand.ActiveConnection = adSSNConnection

'Get the 2 digit month and 2 digit day to use in our archive filename. VBScript does not include a function for this
if (len(CStr(Month(Now))) < 2) then
numericMonth = "0" & CStr(month(now))
else
numericMonth = CStr(month(now))
end if
'Get the 2 digit day. VBScript does not include a function for this
if (len(CStr(day(Now))) < 2) then
numericDay = "0" & CStr(day(now))
else
numericday = CStr(day(now))
end if
'set file name, append todays date in yyyy-mm-dd format so it will display in Alpha order correctly
OUTPUTFILE_LOCATION = "C:\temp\feed-" &amp;amp;amp; year(now) & "-" &amp;amp;amp; numericMonth & "-" &amp;amp;amp; numericDay & ".txt"

'open file for output
'Open OUTPUTFILE_LOCATION For Output As #1
Set objFSO = createobject("scripting.filesystemobject")
Set objStream = objFSO.CreateTextFile(OUTPUTFILE_LOCATION, True)

'get the employees who have completed the course and the SSN’s
Set adEmpsRS = adEmpsCommand.Execute
set adSSNRS = adSSNCommand.Execute

'Go through the resulting recordset for each employee
'On Error Resume Next
Do While (adEmpsRS.EOF <> True)
'get the employees SSN number using the Already existing recordset and just search to find the result rather than requerying.
adSSNRS.MoveFirst
adSSNRS.Find "GEID = '" & adEmpsRS("no_emp") & "'"
'if no SSN is found, do not insert into file
If adSSNRS.EOF = False Then
'Print using Pipe delimited format, using mm-dd-yyyy for year format. First get the date format from our data record, then print
'out using the objStream.Writeline object

'Get the 2 digit month and 2 digit day to use in our archive filename. VBScript does not include a function for this
if (len(CStr(Month(adEmpsRS("dt_ch_compdt")))) < 2) then
numericMonth = "0" & CStr(month(adEmpsRS("dt_ch_compdt")))
else
numericMonth = CStr(month(adEmpsRS("dt_ch_compdt")))
end if

'Get the 2 digit day. VBScript does not include a function for this
if (len(CStr(day(adEmpsRS("dt_ch_compdt")))) < 2) then
numericDay = "0" & CStr(day(adEmpsRS("dt_ch_compdt")))
else
numericday = CStr(day(adEmpsRS("dt_ch_compdt")))
end if

objStream.Writeline adEmpsRS("nm_emp_last") & "" & adEmpsRS("nm_emp_first") & "" & adSSNRS("ssn") & "" & numericMonth & "-" &amp; numericDay & "-" & year(adEmpsRS("dt_ch_compdt"))
End If

'Go to next record and do any pending events
adEmpsRS.MoveNext
Loop

'close and free memory and close file
adEmpsConnection.Close
adSSNConnection.Close