Tuesday, May 19, 2009

Intralink Scripting: Commonspace Folder Info - Part 2

In Part 1, I discussed how to use ILFolderTreeModel to recursively descend through your Commonspace folders to generate a folder list. Coupled with other classes, you can generate even more data about your folders.

In a previous article, I discussed the ObjectInfo subclasses and how to use them to get object metadata. In this article, I'll discuss how to use the ObjectInfo subclass pertaining to Commonspace folders called CSFolderObjectInfo.

The CSFolderObjectInfo class contains many methods to interact with Commonspace folders. The ObjectInfo class are extremely powerful as they let you bypass the user interface and talk directly with the data model of the Intralink client. Despite its name, the CSFolderObjectInfo class contains many methods to perform actions upon Commonspace folders, not just to get information about them.

Examples of methods specific to the CSFolderObjectInfo are: getParent(), getFullPath(), setDescription(), createFolder(), deleteFolder(), moveFolder(), getFilespace(), getReleaseLevel(), getReleaseScheme(), setRelScheme(), etc. Not all of these are guaranteed to work as you may hope. Caution must be exercised before experimenting on your production system. Do so at your own risk.

Before you can apply these methods, you need a CSFolderObjectInfo object. One way to instantiate a CSFolderObjectInfo object is with the static method createByKey() in the ObjectInfo class, although sometimes there are other ways. Here is an example, using the static field tFolder to specify the ObjectInfo object type and a String value for the folder name:

    CSFolderObjectInfo fol_oi = null;
fol_oi = (CSFolderObjectInfo)ObjectInfo.createByKey( ObjectInfo.tFolder, "Root Folder/ProjectX" );

This is a very generic technique that can be applied to most other ObjectInfo data types, even though there are specific createByKey() methods for specific object types.

Example: Release Scheme, File Space, and Release Levels

This example expands upon the code in Part 1, by adding the output of the Release Scheme name, the File Space used, and the Release Levels associated with each folder. Both getReleaseScheme() and getFilespace() return String values of their respective outputs. getReleaseLevel() returns a String array of Release Levels.

    CSFolderObjectInfo fol_oi = null;
List folders = getFolderList(tm, tree);

for (int i=0; i<folders.size(); i++) {

String folderName = folders.get(i).toString();
System.out.println( " " + (i+1) + ": " + folderName );

fol_oi = (CSFolderObjectInfo)ObjectInfo.createByKey( ObjectInfo.tFolder, folderName );

System.out.println( " " + "Release Scheme: " + fol_oi.getReleaseScheme() );
System.out.println( " " + "File Space: " + fol_oi.getFilespace() );

System.out.println( " " + "Release Levels: ");
String[] fol_rellevels = fol_oi.getReleaseLevel();

// release level array values start at 1, but still has element zero
for (int j=1; j<fol_rellevels.length; j++) {
System.out.println( " " + " " + j + ": " + fol_rellevels[j] );

fol_oi = null;

System.out.println(); // blank line for readability
System.out.flush(); // flush to see data in output file immediately

In the next installment, I'll show yet more information about folders that can be gathered, including folder and role based authorizations.

Monday, May 4, 2009

Java: JOptionPane Examples Part 2 - Intermediate

In my previous JOptionPane article, JOptionPane Examples Part 1 - Basic, I covered several examples of basic usage of the JOptionPane dialog. In this installment, we go beyond basic usage and into some functionality that is documented, but not quite so obviously.

In most examples of the JOptionPane dialog, you'll see a String value used for the "message" argument, which is usually the 2nd argument. In the JOptonPane documentation, the "message" argument is listed generically as type Object in the list of methods.

However, if you read at the beginning where the parameters are discussed, the docs state that "message" can not only be a String, but also any subclassed object of the Component class, which is just about any GUI object you could hope to use! But wait there's more!

Not only can it accept practically any GUI object, but it also can accept an array of GUI objects! If an array is provided, the elements of the array are displayed vertically in the dialog box. This is not a very flexible layout, but it is simple and straightforward.

Example 1: Login/Password Dialog

To create a login/password dialog box, we need more than just the login and password fields, but also label fields so the user knows where to type and what goes there.

Here the two field are defined using a JTextField for the login name and a JPassword field for the password. Each field has a corresponding JLabel. Also included, just for fun, is a "remember me" checkbox.

    // Components related to "login" field
JLabel label_loginname = new JLabel("Enter your login name:");
JTextField loginname = new JTextField(15);
// loginname.setText("EnterLoginNameHere"); // Pre-set some text

// Components related to "password" field
JLabel label_password = new JLabel("Enter your password:");
JPasswordField password = new JPasswordField();
// password.setEchoChar('@'); // Sets @ as masking character
// password.setEchoChar('\000'); // Turns off masking

JCheckBox rememberCB = new JCheckBox("Remember me");

The components are wrapped up into an Object array.

    Object[] array = { label_loginname, 
rememberCB };

Then the dialog is initiated using showConfirmDialog(), with "OK" and "Cancel" buttons, and without any icon decorations.

    int res = JOptionPane.showConfirmDialog(null, array, "Login", 

We can respond properly to the user's input, by analyzing the int return value of showConfirmDialog().

    // User hit OK
if (res == JOptionPane.OK_OPTION) { System.out.println( "OK_OPTION" ); }

// User hit CANCEL
if (res == JOptionPane.CANCEL_OPTION) { System.out.println( "CANCEL_OPTION" ); }

// User closed the window without hitting any button
if (res == JOptionPane.CLOSED_OPTION) { System.out.println( "CLOSED_OPTION" ); }

Even though, at this point, the dialog is gone, we can still interact with the GUI components. We can determine if the user entered values, regardless if the user hit OK, Cancel, or just closed the window without hitting any buttons, by using the methods of the various objects.

For example, we'll use getText() to get the login name from the "login name" JTextField object. The password is obtained using getPassword() from the "password" JPasswordField object. The state of the "remember me" checkbox can be determined using the isSelected() method.

    // Output data in "login" field, if any
String newloginname = loginname.getText();
System.out.println( "newloginname: " + newloginname );

// Output data in "password" field, if any
String newpassword = new String(password.getPassword());
System.out.println( "newpassword: " + newpassword );

// Output state of "remember me" check box
boolean selectedCB = rememberCB.isSelected();
System.out.println( "selectedCB: " + selectedCB );

Example 2: Editable JTextArea with JScrollPane scrollbars

In this example, the showMessageDialog() method of the JOptionPane class is used to display a JTextArea, which is going to be pre-populated with some sample text. The size will be set to show 5 rows and 10 columns. The JTextArea is then set to be editable, so the user can change the data.

    JTextArea area = new JTextArea();
JScrollPane scrollpane = new JScrollPane(area);

Along with a JLabel, the JScrollPane object is added to an Object[] array.

    Object[] array = {
new JLabel("Enter some text:"),

The showMessageDialog() method produces a dialog with only an "OK" button and does not return any value.

    JOptionPane.showMessageDialog(null, array, "Text", 

The JTextArea can still be interrogated to see if the user changed the value, if desired.

    String newtext = area.getText();
System.out.println( "newtext: " + newtext );

Example 3: JRadioButton and ButtonGroup

In this example, a dialog will be created consisting of three JRadioButtons and a JTextField. The radio buttons will be associated with a ButtonGroup, which will cause only one of them to be selected at a time.

Create the button objects and make the first button selected by default.

    JRadioButton b1 = new JRadioButton("Option 1");
JRadioButton b2 = new JRadioButton("Option 2");
JRadioButton b3 = new JRadioButton("Option 3");

Tie the JRadioButtons together into a group, allowing only one of the group to be selected.

    ButtonGroup group = new ButtonGroup();

Define a "name" field as well.

    JTextField name = new JTextField(30);

Add the elements together in an array with a few JLabels.

    Object[] array = {
new JLabel("Select an option:"),
new JLabel("Enter a name:"),

Make the dialog appear using showConfirmDialog().

    int res = JOptionPane.showConfirmDialog(null, array, "Select", 

As in the first example, we can analyze the int return value of showConfirmDialog().

    // User hit OK
if (res == JOptionPane.OK_OPTION) { System.out.println( "OK_OPTION" ); }

// User hit CANCEL
if (res == JOptionPane.CANCEL_OPTION) { System.out.println( "CANCEL_OPTION" ); }

// User closed the window without hitting any button
if (res == JOptionPane.CLOSED_OPTION) { System.out.println( "CLOSED_OPTION" ); }

The selected button can be determined using the isSelected() method.

    // User selected button 1
if (b1.isSelected()) { System.out.println( "Selected: Option 1" ); }

// User selected button 2
if (b2.isSelected()) { System.out.println( "Selected: Option 2" ); }

// User selected button 3
if (b3.isSelected()) { System.out.println( "Selected: Option 3" ); }

The name field can be extracted using getText().

    System.out.println( "name=" + name.getText() );

These are just a few examples showing how the JOptionPane class was designed to be very versatile and flexible, allowing for moderately complicated GUI dialog to be created quite easily. Perhaps this usage would have been more obvious if the documentation was clearer, but it is documented.

next time ... part 3 advanced