All Packages  This Package  Class Hierarchy  Class Search  Index

Class app.authkit.envoy.Tool
java.lang.Object
   |
   +----app.authkit.envoy.Tool

  Summary

public abstract class  Tool
     extends java.lang.Object
{
          // Constructors 1
     protected Tool();

          // Methods 24
     protected void addEnvoyTask(Vector, String, String[]);
     protected void addJavaCommand(Vector, String, String[]);
     protected void addOneProperty(Vector, String);
     protected void addPrefixedProperties(Vector, String);
     protected void alert(String, Object[]);
     protected byte[] captureUntilEOF(InputStream, OutputStream, int) throws IOException;
     protected String[] chooseTarget(String, int);
     public void depart(int);
     public void explain(String);
     public void explain(Throwable);
     protected void failed(Throwable, boolean, String);
     protected Object[] getEnvoyMessageParts(String, int, String);
     protected String getJavaPath(String);
     protected String[] makeEnvoyCommand(String, String[], String, String, String, String[]);
     public String mustBeAppBundle(String) throws IOException;
     protected Authorization newAuth();
     protected Frame nonceFrame();
     public abstract void perform(String[]);
     protected void presupposeProperty(String, String);
     protected long schlepUntilEOF(InputStream, OutputStream) throws IOException;
     protected String[] stripPrefixed(String[], String);
     public void tell(String);
     protected String translateEnvoyMessage(byte[]);
     protected int waitForEnvoy(InputStream, OutputStream) throws IOException;
}

A Tool is a class that runs a privileged Envoy process and presents the results. It encapsulates the unprivileged side of peforming privileged Tasks using an Authorization.

Typically, a concrete Tool subclass is given a purpose-specific perform() method along with a completely generalized main() method that calls perform(). But this is only typical, not required. You don't have to give your Tool class a main() method. You don't have to give it a meaningful perform() method. You don't even have to use a Tool class at all to run a privileged Envoy process. It's just a convenient way to do so.

A Tool may represent only a command-line program, only a GUI program, or both, or neither. Some Tool methods refer to AWT classes, but you don't have to use them if you don't want to. If you want to use Swing classes, or some other GUI's classes, you can do that.

Most Tool methods are utility or support methods for doing the things a Tool should do on behalf of an Envoy process:

System Properties Used

"file.encoding"
in addJavaCommand() as a predefined property when building the Envoy process's command-line. Also implicitly used anywhere a PrintStream is created or parsed, such as captureUntilEOF(), schlepUntilEOF(), or waitForEnvoy(); or anywhere encoded bytes are turned into a String, such as translateEnvoyMessage().
"java.class.path"
in addJavaCommand() as the "-cp" parameter when building a 'java' command-line.
"java.home"
in getJavaPath() to determine where javaCommand is located, to construct an absolute pathname.
"os.name"
in newAuth() to determine which Authorization class to instantiate.
"envoy.tasks.between"
a string value, in addEnvoyTask() to precede the task-name when building an Envoy-process command-line.
"alert"
a boolean value, in alert() to decide whether to present a BasicAlert or to do nothing. If alert() isn't called, this property has no effect.
"no-exit"
a boolean value, in depart() to decide whether to call System.exit() or throw a ThreadDeath. If depart() isn't called, this property has no effect.

See Also: Envoy


  Cross Reference

Extended By:
AppBundleLockdown, PerformAsRoot





  Constructors

· Tool

Summary  |  Top
   protected Tool() 

Accessible only to subclasses.



  Methods

· tell

Summary  |  Top
   public void tell(String toTell) 

Emit line of text on stdout.



· explain

Summary  |  Top
   public void explain(String text) 

Emit line of text on stderr, flushing stdout first.



· explain

Summary  |  Top
   public void explain(Throwable toExplain) 

Emit stack trace on stderr, flushing stdout first.



· perform

Summary  |  Top
   public abstract void perform(String[] args) 

Perform this Tool's actions on the given args. Typically called by a concrete Tool's main() method:

		public static void 
		main( String[] args ) 
		{  new ToolSubclass().perform( args );  }



· depart

Summary  |  Top
   public void depart(int status) 

Calls exit() or throws ThreadDeath, depending on "no-exit" property.



· presupposeProperty

Summary  |  Top
   protected void presupposeProperty(String propName, 
                                     String propValue) 

If the system property named by propName is already defined, do nothing. Otherwise, define it to have the non-null propValue.

This is useful when interaction, such as a FileDialog, presupposes subsequent interaction is desirable, such as controlled by the "alert" property.



· newAuth

Summary  |  Top
   protected Authorization newAuth() 

The returned Authorization is unattached to any underlying session. The available concrete imps are hard-wired here, for security reasons.

If the "os.name" property is "Mac OS X", then a MacOSXAuthorization is returned. All other situations, including failure to instantiate a MacOSXAuthorization, return a DenyAllAuthorization.

The concrete classes are referenced by name, using Class.forName(). This avoids invoking an imp's static initializers unless it's actually chosen.



· stripPrefixed

Summary  |  Top
   protected String[] stripPrefixed(String[] array, 
                                    String prefix) 

Strip nulls and Strings that start with prefix, returning a String[]. If no Strings start with prefix, the original array is returned. Useful in other cases, but mainly for stripping "-psn_*" from args.



· nonceFrame

Summary  |  Top
   protected Frame nonceFrame() 

Create a new nonce Frame that isn't intended to be shown, but is only needed as an anchor for a Component or Dialog hierarchy. Called by chooseTarget() and alert().

See Also: chooseTarget, alert



· chooseTarget

Summary  |  Top
   protected String[] chooseTarget(String prompt, 
                                   int kind) 

Choose a target to operate on by presenting a FileDialog. The prompt and kind determine the FileDialog displayed. The resulting selection is returned as a String[], or null if cancelled.

See Also: FileDialogger



· mustBeAppBundle

Summary  |  Top
   public String mustBeAppBundle(String filename)  throws IOException

If an app-bundle, return canonical absolute pathname with symlinks resolved. If not an app-bundle, throw an IOException whose message summarizes why.

This implementation requires the following for success:

  1. the target must exist and be accessible
  2. the target must be a directory
  3. there must be a file "Contents/PkgInfo" nested inside the target directory
  4. the PkgInfo file must be readable and at least 8 bytes long
  5. the PkgInfo file must contain 'APPL' as its first 4 bytes.
  6. the target directory must be resolveable by getCanonicalPath()



· makeEnvoyCommand

Summary  |  Top
   protected String[] makeEnvoyCommand(String javaCmd, 
                                       String[] jvmArgs, 
                                       String envoyClass, 
                                       String envoyPrefix, 
                                       String taskName, 
                                       String[] taskArgs) 

Build a complete command-line to run envoyClass.main() in another process.



· getJavaPath

Summary  |  Top
   protected String getJavaPath(String javaCommand) 

Make an absolute pathname representing a Java interpreter command. It is formed by taking the "java.home" property's value and appending the supplied String with a File.separator between them. If the given String is empty or null, append "bin/java", using appropriate File.separator.



· addJavaCommand

Summary  |  Top
   protected void addJavaCommand(Vector command, 
                                 String javaCommand, 
                                 String[] jvmArgs) 

Start building a 'java' command-line. On return, the Vector contains the command itself, the classpath designation (inherited from self), a "-Dfile.encoding=xxx" so the new process will share this process's default text-encoding, and all the non-null values in jvmArgs.



· addPrefixedProperties

Summary  |  Top
   protected void addPrefixedProperties(Vector command, 
                                        String propPrefix) 

System properties starting with propPrefix are -D'ed onto Vector. A null propPrefix adds no properties. An empty propPrefix adds them all.



· addOneProperty

Summary  |  Top
   protected void addOneProperty(Vector command, 
                                 String propName) 

If property's value is non-null, add a "-Dxx=yy" to the Vector.



· addEnvoyTask

Summary  |  Top
   protected void addEnvoyTask(Vector cmd, 
                               String taskName, 
                               String[] taskArgs) 

Add inter-Task marker, taskName, and taskArgs to cmd Vector. Uses the "envoy.tasks.between" property as the inter-Task marker, or Envoy.TASKS_BETWEEN as the marker's default.



· captureUntilEOF

Summary  |  Top
   protected byte[] captureUntilEOF(InputStream in, 
                                    OutputStream out, 
                                    int captureSize)  throws IOException

Wait for EOF on InputStream, schlepping everything received to OutputStream and capturing the last captureSize bytes to be returned. Neither stream is closed. Calls schlepUntilEOF().



· schlepUntilEOF

Summary  |  Top
   protected long schlepUntilEOF(InputStream in, 
                                 OutputStream out)  throws IOException

Wait for EOF on InputStream, schlepping everything received to OutputStream, using the current Thread rather than an asynchronous daemon Thread. The number of bytes transferred is returned. Neither stream is closed.



· translateEnvoyMessage

Summary  |  Top
   protected String translateEnvoyMessage(byte[] bytes) 

Translate a portion of an Envoy-protocol communication into String form. The portion is typically a captured section, so its bytes may not encode complete characters, if it is in a multi-byte encoding. For safety, though at some loss of robustness, this method first translates all bytes in the range 0x80-0xFF into ?'s as substitutes. That is, all negative bytes are transformed into single-byte characters.

The given byte[] is modified before being turned into a String. The byte[] is encoded using the default encoding (i.e. "file.encoding").



· getEnvoyMessageParts

Summary  |  Top
   protected Object[] getEnvoyMessageParts(String text, 
                                           int index, 
                                           String marker) 

Extract an Envoy message identified by marker, from the text starting at index. The message begins at the first appearance of the marker, and ends at the first following appearance of Envoy.PROTOCOL_NEWLINE. The message is then separated into parts by Envoy.PROTOCOL_DELIM, which are returned as an Object[] containing String and Integer values.

The index tells where to start scanning the text for the marker, and in which direction. Non-negative values count from the start of the text and scan towards the end. Negative index values count from past the end of the text and scan towards the start. So -1 means the last char, -2 the next to last, etc. The Envoy.PROTOCOL_NEWLINE always follows the marker, so it is always searched for by scanning towards the end of the text.

Returns an array containing mixed String and/or Integer values. Any piece that can be converted to an Integer is returned as an Integer. Any piece that can't be converted to an Integer is returned as a String.

This method uses Envoy's protocol strings, and relies on knowledge of their format. If the Envoy protocol is changed, this method must also change.



· waitForEnvoy

Summary  |  Top
   protected int waitForEnvoy(InputStream in, 
                              OutputStream out)  throws IOException

Wait for an Envoy-protocol 'stop' message on InputStream, echoing the data to the OutputStream, and parsing the Envoy's final status from the data.

If the OutputStream is null, the Envoy protocol stream is parsed for an Envoy STOP message, but otherwise consumed.

Parsing failures throw an IOException whose message summarizes the reason for failure. This method relies on knowledge of Envoy's protocol format, The PROTOCOL_STOP message in particular. If the Envoy protocol is changed, this method must also change.



· failed

Summary  |  Top
   protected void failed(Throwable why, 
                         boolean stackTrace, 
                         String alertTitle) 

Emit to stderr, then call alert().



· alert

Summary  |  Top
   protected void alert(String alertTitle, 
                        Object[] alertLines) 

Show a modal BasicAlert if "alert" property is true, or do nothing if it's false. The BasicAlert has a 5- to 12-line by 50-char text-area, with no scrollbars or only a vertical one. The alertText will be added as lines, one for each Object.toString(). If a String contains newlines, those will be additional lines. The supplied alertText lines will be wrapped to fit, though not necessarily word-wrapped.

If you need a more flexible BasicAlert, make your own or define an override.



All Packages  This Package  Class Hierarchy  Class Search  Index
Freshly brewed Java API Documentation automatically generated with polardoc Version 1.0.7