Writing Custom Code

Custom Code Actions

Custom code actions allow you to create nongraphical actions that can manipulate data on your target system, affect InstallAnywhere variables, prepopulate various install options, or even execute native code (via JNI or native executions). In fact, custom code actions allow you to perform nearly any action possible with Java.

A Custom Code Action Example

This section describes how to write your own custom code action and leads you through an example (called com.zerog.ia.customcode.samples. SampleAction). This section doesn't explain how to make your code work with InstallAnywhere's advanced designer or the Execute Custom Code action.

NOTE

We assume that you know the goals of your action, but have not yet written any code to implement it. After each relevant step, we will show an example of how this can be done.


1.
Create your main class file and package it. This is the file that you will specify in the Class field in the InstallAnywhere advanced designer (see Chapter 20).

package com.zerog.ia.customcode.samples;

2.
To create a custom action, your class must first extend the abstract class com.zerog.ia.api.pub.CustomCodeAction. This class provides the interface through which you will interact with the InstallAnywhere runtime.

package com.zerog.ia.customcode.samples;

import com.zerog.ia.api.pub.*;

public class SampleAction extends CustomCodeAction
{
  public void install(InstallerProxy ip) {}
  public void uninstall(UninstallerProxy up) {}
  public String getInstallStatusMessage() {}
  public String getUninstallStatusMessage() {}
}

3.
Description of public void install (InstallerProxy ip) {}.

The installer calls this method at the point during installation where the custom code action was added. The InstallerProxy instance provides methods to access installer information, set installation status, and control installation flow. SampleAction will display a message to the end-user in a modal dialog.

package com.zerog.ia.customcode.samples;

import com.zerog.ia.api.pub.*;
import java.awt.*;
import java.awt.event.*;
public class SampleAction extends CustomCodeAction implements ActionListener
{
  public void install(InstallerProxy ip){
    // Get Some Variables from the Variable Manager
    String title = ip.substitute ("$SAMPLE_ACTION_TITLE$");
    String msg = ip.substitute ("$SAMPLE_ACTION_MESSAGE$");

    Label l = new Label (msg);

    Button b = new Button ("Close");
    // For internationalization, the button label could be
    // externalized and referenced as follows:
    //
    // Button b = new Button (ip.getValue
    ("SampleAction.Close"));
    b.addActionListener (this);

    // Here we create a dummy Frame to use as the parent
    // for the Dialog - it is never shown.
    Frame myFrame = new Frame();

    Dialog myDialog = new Dialog (myFrame, title, true);
    Dimension bounds = Toolkit.getDefaultToolkit
    ().getScreenSize();

    myDialog.setLayout(new BorderLayout());

    myDialog.add(BorderLayout.NORTH, l);
    myDialog.add(BorderLayout.CENTER, b);
    myDialog.pack();

    // Here we center the Dialog
    Rectangle abounds = myDialog.getBounds();

    myDialog.setLocation((bounds.width - abounds.width) / 2,
    (bounds.height - abounds.height) / 2);

    myDialog.show();
  }
  public void uninstall(UninstallerProxy up) { }
  public String getInstallStatusMessage() { }
  public String getUninstallStatusMessage() { }
  public void actionPerformed(ActionEvent ae)
  {
    // Dispose the dialog and its hidden parent frame.
    Button source = (Button) ae.getSource();
    Dialog parent = (Dialog) source.getParent();
    Frame fparent = (Frame) parent.getParent();
    parent.dispose();
    fparent.dispose();
  }
}

4.
Description of public void uninstall (UninstallerProxy up) {}.

This method is called by the uninstaller at uninstall time before the deletion of any files. The UninstallerProxy instance provides access to any information written at install time. SampleAction will display a small window with a message.

public void uninstall(UninstallerProxy up)
{
  String title = "Uninstall";

  Button b = new Button("Close");
  b.addActionListener(this);

  Frame myFrame = new Frame();

  Dialog myDialog = new Dialog (myFrame, title, true);
  Dimension bounds =
  Toolkit.getDefaultToolkit().getScreenSize()

  myDialog.setLayout(new BorderLayout());

  myDialog.add(BorderLayout.NORTH, l);
  myDialog.add(BorderLayout.CENTER, b);
  myDialog.pack();

  // Here we center the Dialog
  Rectangle abounds = myDialog.getBounds();

  myDialog.setLocation((bounds.width - abounds.width) / 2,
  (bounds.height - abounds.height) / 2);

  myDialog.show();
}

5.
Description of public String getInstallStatusMessage() {}.

The installer calls this message to display a status message in the progress bar during installation. The message is displayed while the install (InstallerProxy ip) method is called. The method has no effect if the action is a pre-install or post-install action.

public String getInstallStatusMessage()
{
  return "Displaying a small installation message...";
}

6.
Description of public String getUninstallStatusMessage() {}.

This method is called by the uninstaller to display a status message in the progress bar during uninstall. The message is displayed while the uninstall (UninstallerProxy up) method is called.

public String getUninstallStatusMessage()
{
  return "Displaying a long uninstallation message...";
}

7.
Description of CustomCodeAction member variables.

The CustomCodeAction class provides InstallerProxy and UninstallerProxy as member variables. Use these to access the proxies at any point during execution of the custom code actions, rather than only during installation/uninstallation. Uninstall and install still receive proxies as parameters while called; this is for ease of use as well as for backwards compatibility. You can use either the passed proxy or the member variable proxy and receive the exact same functionality inside these functions. See the Javadoc for CustomCodeAction on the Zero G Web site for more information (www.zerog.com/downloads_04.html).

Custom Code Panels

At times you may find that InstallAnywhere's included panels don't meet your needs. InstallAnywhere's API addresses this with the introduction of custom code panels, which are the graphical equivalent of custom code actions. They allow you to present a UI to your end-user in combination with any task that you may need in a graphical installer.

Custom code panels provide you with a framework to which you can add components necessary for your particular task. Each custom code panel extends the core InstallAnywhere Install panel and, as such, provides your custom developed panel with the same look and feel and the same available elements as the standard InstallAnywhere panels. The default custom code panel provides the framework for both AWT and Swing elements.

public boolean setupUI(CustomCodePanelProxy ip)
{
// clear panel if setupUI is called multiple times
 if(true)
     removeAll();
     // set up layout manager
 setLayout(new FlowLayout());
 Label label1 = new Label("Custom Code Panel Test");
 add(label1);
 return true;
}

A Custom Code Panel Example

This section describes how to write your own custom code panel and leads you through an example (named com.zerog.ia.customcode.samples. SamplePanel). This section doesn't explain how to make your code work with InstallAnywhere's advanced designer or the Custom Code Panel action.

NOTE

We assume that you know the goals of your panel, but have not yet written any code that implements it. After each relevant step, we will show an example of how this can be done.


1.
Create your main class file and package it. This is the file that you will specify in the Class field in the InstallAnywhere advanced designer.

package com.zerog.ia.customcode.samples;

2.
To create a custom action, your class needs to extend the abstract class com.zerog.ia.api.pub.CustomCodePanel. This class provides the interface for interacting with the InstallAnywhere installer.

package com.zerog.ia.customcode.samples;

import com.zerog.ia.api.pub.*;

public class SamplePanel extends CustomCodePanel
{
  public boolean setupUI(CustomCodePanelProxy
  customCodePanelProxy) {}
  public void panelIsDisplayed() {}
  public boolean okToContinue() {}
  public boolean okToGoPrevious(){}
  public String getTitle() {}
}

3.
Description of public boolean setupUI(CustomCodePanelProxy customCodePanelProxy) {}.

This method gets called prior to the panel's being displayed. This is useful for initializing the contained components and variables. SamplePanel will use another example class, BrowserLauncher, to demonstrate how to launch a URL through a custom code panel. To do this, import the class edu.stanford.ejaldbert.BrowserLauncher and make sure to include this class file in the custom code panel JAR archive. Use the setupUI method to set up the UI and add components to your panel. This step includes adding labels, text fields, buttons, and an ActionListener. You'll want to ensure that you specify a LayoutManager for your panel. Although custom code panels do specify a default FlowLayout, specifying the LayoutManager will make your components appear as you expect within the InstallAnywhere custom code panel framework. This example also creates a few member variables of the SampleConsole class.

package com.zerog.ia.customcode.samples;
import com.zerog.ia.api.pub.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import edu.stanford.cs.ejalbert.*;
public class SamplePanel extends CustomCodePanel implements ActionListener
{
  private boolean inited = false;
  private TextField tf;
  private Button b;

  public boolean setupUI(CustomCodePanelProxy
  customCodePanelProxy)
  {
    // Use a boolean flag here to prevent duplicate GUI
    // elements.
    if (inited == true)
    return true;
    inited = true;

    Label label = new Label ("URL");
    label.setFont(new Font("Dialog", Font.BOLD, 12));

    b = new Button("Go");
    b.addActionListener(this);

    tf = new TextField (40);

    // Get a default URL string from InstallAnywhere and
    // use it if it is not empty.
    String def =
    customCodePanelProxy.substitute("$DEFAULT_URL$");
    System.out.println("Def: " + def);
    if (!def.equals(""))
    {
      tf.setText(def);
    }
    else tf.setText("www.ZeroG.com");

    add(label);
    add(tf);
    add(b);

    return true;
  }
  public void panelIsDisplayed() {}
  public boolean okToContinue() {}
  public boolean okToGoPrevious(){}
  public String getTitle() {}
}

4.
Description of public void panelIsDisplayed(UninstallerProxy up) {}.

This method is called immediately after the panel is displayed. This is useful for doing some processing while the panel is displayed without having to wait for the okToContinue method to be called. Of course, this method will never be called if setupUI() returns false. SamplePanel does nothing during this method and is left empty.

public void panelIsDisplayed()
{
}

5.
Description of public boolean okToContinue() {}.

This method gets called before the installer continues. If this method returns true, then the installer continues to the next action; otherwise the installer prevents the user from continuing. This is useful for verifying end-user input or setting InstallAnywhere variables. In the SamplePanel an InstallAnywhere variable is set before the installer continues.

public boolean okToContinue()
{
  // Set an IA variable based upon the textfield's value,
  // then continue.
  customCodePanelProxy.setVariable("$CHOSEN_URL$",
  tf.getText());
  return true;
}

6.
Description of public boolean okToGoPrevious() {}.

Like okToContinue(), this method gets called prior to a return to a previous step in the installer if the end-user clicks the Previous button. In the SamplePanel this method simply returns true.

public boolean okToGoPrevious()
{
  return true;
}

7.
Description of public String getTitle() {}.

This method returns the string to be displayed as the title of this panel. In SamplePanel “Launch URL” is returned as the title.

public String getTitle()
{
  return "Launch URL";
}

8.
Description of CustomCodePanel member variables.

The CustomCodePanel class provides CustomCodePanelProxy as a member variable. This panel allows developers to access the proxy at any point during execution of the custom code panel, rather than only during setupUI. While setupUI is called, it still receives CustomCodePanelProxy as a parameter (for ease of use as well as backward compatibility). Inside this method, it is important to note that you can use either the passed proxy or the member variable proxy and receive the exact same functionality.

Custom Code Consoles

InstallAnywhere's custom code console provides a similar, customizable framework to that provided by the custom code panel, which allows you to add components of your choosing to a generic InstallAnywhere interface. This console will allow the installer to display text or extract information from the end-user when running in Console mode.

The framework is designed to provide a text-only interface, and as such, the available components are somewhat different.

A simple custom code console might look as follows:

==================================================================
Test Console
——————
Please select one of the following options.
->1- first choice
  2- second choice
  3- third choice
ENTER THE NUMBER FOR YOUR CHOICE, OR PRESS <ENTER> TO ACCEPT THE DEFAULT:
==================================================================

A Custom Code Console Action Example

This section describes how to write your own custom code console action, by leading you through an example (com.zerog.ia.customcode.samples. CustomCodeConsoleAction). This section doesn't explain how to make your code work with InstallAnywhere's advanced designer.

NOTE

We assume that you know the goals of your console action, but have not yet written any code that implements them. After each relevant step, we will show an example of how this can be done.


1.
Create your main class file and package it. This is the file that you will specify in the Class field in the InstallAnywhere advanced designer.

package com.zerog.ia.customcode.samples;

2.
To create a custom console action, your class must first extend the abstract class com.zerog.ia.api.pub.CustomCodeConsoleAction. This class provides the interface through which you will interact with the InstallAnywhere runtime.

package com.zerog.ia.customcode.samples;
  import com.zerog.ia.api.pub.*;
  public class SampleAction extends CustomCodeConsoleAction
{
  public boolean setup() {}
  public void executeConsoleAction() throws
  PreviousRequestException{}
  public String getTitle() {}
}

3.
Description of public boolean setup() {}.

The installer calls this method prior to the console action being displayed. This method is useful for the initialization needed by the action and returns true if the console should be displayed. If this method returns false, the console is not displayed and the installer continues with the next action. This custom code console action example uses the setup() method to populate a vector from an InstallAnywhere variable.

package com.zerog.ia.customcode.samples;
  import com.zerog.ia.api.pub.*;
  import java.util.vector;
  import java.util.StringTokenizer;
public class SampleConsole extends CustomCodeConsoleAction
{

  public boolean setup()
{
    // Use a StringTokenizer to populate the vector
    // 'choices' from the InstallAnywhere variable
    // $SAMPLE_CONSOLE_LIST$

    String list = cccp.substitute("$SAMPLE_CONSOLE_LIST$");
    StringTokenizer st = new StringTokenizer(list, ",");

    while (st.hasMoreTokens())
    {
      choices.addElement(st.nextToken());
    }
    return true;
  }

  public void executeConsoleAction() throws
  PreviousRequestException{}
  public String getTitle(){}
}

4.
Description of public void executeConsoleAction() {}.

This method is called when the installer is ready to display the console action. Most, if not all, of the console input and output should originate from the call into this action via this method. This example uses the executeConsoleAction method to prompt the end-user to select a choice from a list.

public void executeConsoleAction() throws
PreviousRequestException
{
  // Get an instance of ConsoleUtils. We will use
  // ConsoleUtils to help construct the console prompts.
  ConsoleUtils cu =
    (ConsoleUtils)cccp.getService(ConsoleUtils.class);

  // Use the substitute method to get the variable:
  // $SAMPLE_CONSOLE_PROMPT$
  String prompt = cccp.substitute("$SAMPLE_CONSOLE_PROMPT$");

  // Use the built in features of the ConsoleUtils class to
  // ask the user to select from a list
  int userChoice = cu.createChoiceListAndGetValue(prompt,
    choices);

  // Set the result as an InstallAnywhere variable
  String result = choices.elementAt(userChoice).toString();
  cccp.setVariable(""$SAMPLE_CONSOLE_CHOICE$", result);
}

5.
Description of public String getTitle() {}.

This method returns the string to be displayed as the title of this console. This example just returns “Sample Console” as the title.

public String getTitle()
{
  String title = "Sample Console";
  return title;
}

6.
Description of CustomCodeAction member variables.

The CustomCodeConsoleAction class provides CustomCodePanelProxy cccp, but instances of the class ConsoleUtils must be instantiated specifically.

Custom Code Rules

InstallAnywhere's rules architecture allows you to extend the existing rule set by adding custom code rules. These rules, based on the InstallAnywhere API, provide you with a method of making any action in the InstallAnywhere installer conditional. However, unlike the built-in rules, your code provides the condition. This feature is especially useful in situations where your action is dependant on a variable outside of the InstallAnywhere architecture.

An InstallAnywhere custom code rule is effectively an action that, when executed, returns a simple Boolean value. If the rule returns true, the action to which it is attached will install or execute. If the rule returns false, the action will be prevented from occurring.

A Custom Code Rule Example

This section describes how to write your own custom code rule and leads you through an example (called com.zerog.ia.customcode.samples. SampleRule). This section doesn't explain how to make your code work with InstallAnywhere's advanced designer.

NOTE

We assume that you know the goals of your rule, but have not yet written any code to implement it. After each relevant step, we will show an example of how this can be done.


1.
Create your main class file and package it. You will specify this file in the Class field in the InstallAnywhere advanced designer.

package com.zerog.ia.customcode.samples;

2.
To create a custom rule, your class must first extend the abstract class com.zerog.ia.api.pub.CustomCodeRule. This class provides the interface through which you will interact with the InstallAnywhere runtime.

package com.zerog.ia.customcode.samples;
import com.zerog.ia.api.pub.*;
public class SampleRule extends CustomCodeRule
{
  public abstract boolean evaluateRule()
}

3.
Description of public abstract boolean evaluateRule().

This method is called at install-time when the installer is evaluating the rules set on a given installer action. It is very important that this method return quickly so that unnecessary lag is not experienced.

package com.acme;
// You should change this to your own package
import com.zerog.ia.api.pub.*;
public class CustomCodeRuleTemplate extends CustomCodeRule
{
  public boolean evaluateRule()
{
    //This method resolves all of the InstallAnywhere
    //variables in a string. If the string contains a
    //variable, and resolving that variable then contains
    //another variable, that too will be resolved until all
    //variables have been resolved. If a variable cannot be
    //resolved, it evaluates to an empty string ("").
    String myString = ruleProxy.substitute("$myVariable$");
    //This method returns the value of the named variable.
    //If no variable is
    //defined for that name, returns null.
    String myString = (String)
    ruleProxy.getVariable("myVariable");
    //This method sets the named variable to refer to the
    //value. If the variable was already set, its previous
    //value is returned. Otherwise, returns null.
    Object previousValue =
    ruleProxy.setVariable("myVariable", "theValue");
    //For Internationalization support. Gives access to
    //locale-specific static GUI strings.
    String myString = ruleProxy.getValue("myKey",
    Locale.ENGLISH);
    //For Internationalization support. Gives access to
    //locale-specific static GUI strings. Returns the
    //resource for the user's chosen installation locale.
    String myString = ruleProxy.getValue("myKey")
    return true;
  }
}

4.
Description of CustomCodeRule member variables.

The CustomCodeRule class provides CustomCodeRuleProxy as a member variable. This allows developers to access the proxy at any point during the execution of the custom code rule, rather than only during evaluateRule.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.57.16